× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

Make Asynchronous Calls Inside a Loop

Michael Perrenoud
Mar 17, 2015
<p>Today's applications require a lot of data to be loaded asynchronously. Often times that data is hierarchical. However, loading data asynchronously inside of a <code>for</code> loop in JavaScript is problematic. Consider the following, albeit contrived, example:</p> <pre><code class="language-javascript">var parents = [ { Name: 'Mike Perrenoud', AddressId: 1 }, { Name: 'Bob Perrenoud', AddressId: 2 }, { Name: 'Bill Perrenoud', AddressId: 3 } ]; for (var i = 0; i &lt; parents.length; i++) { service.get(parents[i].AddressId) .then(function(response) { parents[i].Address = response.Address; // and more fields here }); }</code></pre> <p>While this code looks pretty good, it doesn't work. The promise won't be resolved in time. In fact, it's plausible that the only <code>parent</code> to get an address will be the last one. Furthermore, it's also plausible that address could be any of them. However, there is a really simple solution:</p> <pre><code class="language-javascript">var parents = [ { Name: 'Mike Perrenoud', AddressId: 1 }, { Name: 'Bob Perrenoud', AddressId: 2 }, { Name: 'Bill Perrenoud', AddressId: 3 } ]; for (var i = 0; i &lt; parents.length; i++) { (function(p) { service.get(p.AddressId) .then(function(response) { p.Address = response.Address; // and more fields here }); })(parents[i]); }</code></pre> <p>This is an IIFE that has now created a closure. The importance of this technique is that you are injecting a specific parent, the one currently at <code>parents[i]</code>, into a function by which it will never change. Now it doesn't matter when these promises resolve, they will always update the right <code>parent</code>.</p> <p>Until next time - happy coding!</p>

Get New Tutorials Delivered to Your Inbox

New tutorials will be sent to your Inbox once a week.

comments powered by Disqus