You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2012-11-5-async.md
+15-16Lines changed: 15 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ for (var i = 0; i < 100; i++) {
20
20
console.log('You might think this gets printed last.')
21
21
{% endhighlight %}
22
22
23
-
Go back to your command window and list files in your current working directory. Notice that the only file created was `3.json`. This is because the callback for setTimeout doesn't actually get executed until the for loop has completed. Any other statements after the for loop would also be executed before the callback. This is, in part, because Node is single threaded. The event loop hasn't had a chance to invoke your callback. In any case, all of the callbacks are being fired with the same value of `i`.
23
+
Notice the value printed is 100, which is the terminal condition for this loop. This is because the callback for setTimeout doesn't actually get executed until the for loop has completed. Any other statements after the for loop would also be executed before the callback. This is, in part, because Node is single threaded. The event loop hasn't had a chance to invoke your callback. In any case, all of the callbacks are being fired with the same value of `i`.
24
24
25
25
How do we avoid this? The important concept here is how scope is handled in JavaScript. Unlike other languages that use block level scope, JavaScript's scope is at a function level. We can get around this problem by introducing a new scope in each iteration of the loop to capture the value of `i` at that moment:
26
26
@@ -53,33 +53,32 @@ console.log('this still gets printed first.')
53
53
54
54
## Asynchronous calls in parallel and then joining them
55
55
56
-
So how do we go about printing out a something after the loops work has been done.
56
+
So how do we go about printing out a something after the loops work has been done?
57
57
58
-
More often than not there's a need to invoke a set of tasks asynchronously and then start a new set of tasks after completion. There are a variety of libraries that help with performing this situation and cleaning up the code a lot.
58
+
More often than not there's a need to invoke a set of tasks asynchronously and then start a new set of tasks after completion. There are a variety of libraries that help with performing this situation and cleaning up the code a lot.
59
59
60
60
{% highlight javascript %}
61
-
var printNumberLater = function (i, cb) {
62
-
setTimeout(function () {
63
-
console.log(i);
64
-
cb();
65
-
}, 100);
66
-
};
67
-
68
61
var totalNumbersToPrint = 100;
69
62
var finishedCount = 0;
70
63
71
-
for (var i = 0; i < totalNumbersToPrint; i++) {
72
-
printNumberLater(i, function () {
73
-
finishedCount++;
64
+
var printNumberLater = function (i) {
65
+
setTimeout(function () {
66
+
console.log(i);
74
67
68
+
finishedCount++;
69
+
75
70
if (finishedCount === totalNumbersToPrint) {
76
71
console.log('this finally gets printed after all work is done!');
77
72
}
78
-
});
73
+
}, 100);
74
+
};
75
+
76
+
for (var i = 0; i < totalNumbersToPrint; i++) {
77
+
printNumberLater(i);
79
78
}
80
79
{% endhighlight %}
81
80
82
-
In the example above, note that we keep track of how many times the `readFile` callback is invoked. Once the value matches the number of callbacks we're waiting on we can continue with saving off the biographies. This can get quite ugly the more complex your application becomes. A very good library for dealing with this is `async`. Here's an example of how async could be used to clean up the code above.
81
+
In the example above, note that we keep track of how many times the `setTimeout` callback is invoked. Once the value matches the number of callbacks we're waiting on we can continue with printing out our message. This can get quite ugly the more complex your application becomes. A very good library for dealing with this is `async`. Here's an example of how async could be used to clean up the code above.
83
82
84
83
First, you should install the async module.
85
84
@@ -109,7 +108,7 @@ async.parallel(workToBeDone, function () {
109
108
});
110
109
{% endhighlight %}
111
110
112
-
Imagine the above where you had multiple things needing to happen in parallel. Remember how we kept around the `biosParsed` counter a few examples back? Keeping track of all the counters for more complicated examples could get extremely messy. Using `async` we're able to avoid these arbitrary counters and organize our code better. Another pattern to use is called `promises`.
111
+
Imagine the above where you had multiple things needing to happen in parallel. Remember how we kept around the `finishedCount` counter a few examples back? Keeping track of all the counters for more complicated examples could get extremely messy. Using `async` we're able to avoid these arbitrary counters and organize our code better. Another pattern to use is called `promises`.
0 commit comments