UNPKG

37.2 kBMarkdownView Raw
1# Async.js
2
3Async is a utility module which provides straight-forward, powerful functions
4for working with asynchronous JavaScript. Although originally designed for
5use with [node.js](http://nodejs.org), it can also be used directly in the
6browser.
7
8Async provides around 20 functions that include the usual 'functional'
9suspects (map, reduce, filter, forEach…) as well as some common patterns
10for asynchronous control flow (parallel, series, waterfall…). All these
11functions assume you follow the node.js convention of providing a single
12callback as the last argument of your async function.
13
14
15## Quick Examples
16
17```javascript
18async.map(['file1','file2','file3'], fs.stat, function(err, results){
19 // results is now an array of stats for each file
20});
21
22async.filter(['file1','file2','file3'], path.exists, function(results){
23 // results now equals an array of the existing files
24});
25
26async.parallel([
27 function(){ ... },
28 function(){ ... }
29], callback);
30
31async.series([
32 function(){ ... },
33 function(){ ... }
34]);
35```
36
37There are many more functions available so take a look at the docs below for a
38full list. This module aims to be comprehensive, so if you feel anything is
39missing please create a GitHub issue for it.
40
41
42## Download
43
44Releases are available for download from
45[GitHub](http://github.com/caolan/async/downloads).
46Alternatively, you can install using Node Package Manager (npm):
47
48 npm install async
49
50
51__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 17.5kb Uncompressed
52
53__Production:__ [async.min.js](https://github.com/caolan/async/raw/master/dist/async.min.js) - 1.7kb Packed and Gzipped
54
55
56## In the Browser
57
58So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:
59
60```html
61<script type="text/javascript" src="async.js"></script>
62<script type="text/javascript">
63
64 async.map(data, asyncProcess, function(err, results){
65 alert(results);
66 });
67
68</script>
69```
70
71## Documentation
72
73### Collections
74
75* [forEach](#forEach)
76* [map](#map)
77* [filter](#filter)
78* [reject](#reject)
79* [reduce](#reduce)
80* [detect](#detect)
81* [sortBy](#sortBy)
82* [some](#some)
83* [every](#every)
84* [concat](#concat)
85
86### Control Flow
87
88* [series](#series)
89* [parallel](#parallel)
90* [whilst](#whilst)
91* [doWhilst](#doWhilst)
92* [until](#until)
93* [doUntil](#doUntil)
94* [waterfall](#waterfall)
95* [queue](#queue)
96* [cargo](#cargo)
97* [auto](#auto)
98* [iterator](#iterator)
99* [apply](#apply)
100* [nextTick](#nextTick)
101* [times](#times)
102* [timesSeries](#timesSeries)
103
104### Utils
105
106* [memoize](#memoize)
107* [unmemoize](#unmemoize)
108* [log](#log)
109* [dir](#dir)
110* [noConflict](#noConflict)
111
112
113## Collections
114
115<a name="forEach" />
116### forEach(arr, iterator, callback)
117
118Applies an iterator function to each item in an array, in parallel.
119The iterator is called with an item from the list and a callback for when it
120has finished. If the iterator passes an error to this callback, the main
121callback for the forEach function is immediately called with the error.
122
123Note, that since this function applies the iterator to each item in parallel
124there is no guarantee that the iterator functions will complete in order.
125
126__Arguments__
127
128* arr - An array to iterate over.
129* iterator(item, callback) - A function to apply to each item in the array.
130 The iterator is passed a callback(err) which must be called once it has completed.
131 If no error has occured, the callback should be run without arguments or
132 with an explicit null argument.
133* callback(err) - A callback which is called after all the iterator functions
134 have finished, or an error has occurred.
135
136__Example__
137
138```js
139// assuming openFiles is an array of file names and saveFile is a function
140// to save the modified contents of that file:
141
142async.forEach(openFiles, saveFile, function(err){
143 // if any of the saves produced an error, err would equal that error
144});
145```
146
147---------------------------------------
148
149<a name="forEachSeries" />
150### forEachSeries(arr, iterator, callback)
151
152The same as forEach only the iterator is applied to each item in the array in
153series. The next iterator is only called once the current one has completed
154processing. This means the iterator functions will complete in order.
155
156
157---------------------------------------
158
159<a name="forEachLimit" />
160### forEachLimit(arr, limit, iterator, callback)
161
162The same as forEach only the iterator is applied to batches of items in the
163array, in series. The next batch of iterators is only called once the current
164one has completed processing.
165
166__Arguments__
167
168* arr - An array to iterate over.
169* limit - How many items should be in each batch.
170* iterator(item, callback) - A function to apply to each item in the array.
171 The iterator is passed a callback which must be called once it has completed.
172 If no error has occured, the callback should be run without arguments or
173 with an explicit null argument.
174* callback(err) - A callback which is called after all the iterator functions
175 have finished, or an error has occurred.
176
177__Example__
178
179```js
180// Assume documents is an array of JSON objects and requestApi is a
181// function that interacts with a rate-limited REST api.
182
183async.forEachLimit(documents, 20, requestApi, function(err){
184 // if any of the saves produced an error, err would equal that error
185});
186```
187
188---------------------------------------
189
190<a name="map" />
191### map(arr, iterator, callback)
192
193Produces a new array of values by mapping each value in the given array through
194the iterator function. The iterator is called with an item from the array and a
195callback for when it has finished processing. The callback takes 2 arguments,
196an error and the transformed item from the array. If the iterator passes an
197error to this callback, the main callback for the map function is immediately
198called with the error.
199
200Note, that since this function applies the iterator to each item in parallel
201there is no guarantee that the iterator functions will complete in order, however
202the results array will be in the same order as the original array.
203
204__Arguments__
205
206* arr - An array to iterate over.
207* iterator(item, callback) - A function to apply to each item in the array.
208 The iterator is passed a callback which must be called once it has completed
209 with an error (which can be null) and a transformed item.
210* callback(err, results) - A callback which is called after all the iterator
211 functions have finished, or an error has occurred. Results is an array of the
212 transformed items from the original array.
213
214__Example__
215
216```js
217async.map(['file1','file2','file3'], fs.stat, function(err, results){
218 // results is now an array of stats for each file
219});
220```
221
222---------------------------------------
223
224<a name="mapSeries" />
225### mapSeries(arr, iterator, callback)
226
227The same as map only the iterator is applied to each item in the array in
228series. The next iterator is only called once the current one has completed
229processing. The results array will be in the same order as the original.
230
231
232---------------------------------------
233
234<a name="mapLimit" />
235### mapLimit(arr, limit, iterator, callback)
236
237The same as map only the iterator is applied to batches of items in the
238array, in series. The next batch of iterators is only called once the current
239one has completed processing.
240
241__Arguments__
242
243* arr - An array to iterate over.
244* limit - How many items should be in each batch.
245* iterator(item, callback) - A function to apply to each item in the array.
246 The iterator is passed a callback which must be called once it has completed.
247 If no error has occured, the callback should be run without arguments or
248 with an explicit null argument.
249* callback(err, results) - A callback which is called after all the iterator
250 functions have finished, or an error has occurred. Results is an array of the
251 transformed items from the original array.
252
253__Example__
254
255```js
256async.map(['file1','file2','file3'], 1, fs.stat, function(err, results){
257 // results is now an array of stats for each file
258});
259```
260
261---------------------------------------
262
263<a name="filter" />
264### filter(arr, iterator, callback)
265
266__Alias:__ select
267
268Returns a new array of all the values which pass an async truth test.
269_The callback for each iterator call only accepts a single argument of true or
270false, it does not accept an error argument first!_ This is in-line with the
271way node libraries work with truth tests like path.exists. This operation is
272performed in parallel, but the results array will be in the same order as the
273original.
274
275__Arguments__
276
277* arr - An array to iterate over.
278* iterator(item, callback) - A truth test to apply to each item in the array.
279 The iterator is passed a callback which must be called with a boolean argument
280 once it has completed.
281* callback(results) - A callback which is called after all the iterator
282 functions have finished.
283
284__Example__
285
286```js
287async.filter(['file1','file2','file3'], path.exists, function(results){
288 // results now equals an array of the existing files
289});
290```
291
292---------------------------------------
293
294<a name="filterSeries" />
295### filterSeries(arr, iterator, callback)
296
297__alias:__ selectSeries
298
299The same as filter only the iterator is applied to each item in the array in
300series. The next iterator is only called once the current one has completed
301processing. The results array will be in the same order as the original.
302
303---------------------------------------
304
305<a name="reject" />
306### reject(arr, iterator, callback)
307
308The opposite of filter. Removes values that pass an async truth test.
309
310---------------------------------------
311
312<a name="rejectSeries" />
313### rejectSeries(arr, iterator, callback)
314
315The same as reject, only the iterator is applied to each item in the array
316in series.
317
318
319---------------------------------------
320
321<a name="reduce" />
322### reduce(arr, memo, iterator, callback)
323
324__aliases:__ inject, foldl
325
326Reduces a list of values into a single value using an async iterator to return
327each successive step. Memo is the initial state of the reduction. This
328function only operates in series. For performance reasons, it may make sense to
329split a call to this function into a parallel map, then use the normal
330Array.prototype.reduce on the results. This function is for situations where
331each step in the reduction needs to be async, if you can get the data before
332reducing it then its probably a good idea to do so.
333
334__Arguments__
335
336* arr - An array to iterate over.
337* memo - The initial state of the reduction.
338* iterator(memo, item, callback) - A function applied to each item in the
339 array to produce the next step in the reduction. The iterator is passed a
340 callback which accepts an optional error as its first argument, and the state
341 of the reduction as the second. If an error is passed to the callback, the
342 reduction is stopped and the main callback is immediately called with the
343 error.
344* callback(err, result) - A callback which is called after all the iterator
345 functions have finished. Result is the reduced value.
346
347__Example__
348
349```js
350async.reduce([1,2,3], 0, function(memo, item, callback){
351 // pointless async:
352 process.nextTick(function(){
353 callback(null, memo + item)
354 });
355}, function(err, result){
356 // result is now equal to the last value of memo, which is 6
357});
358```
359
360---------------------------------------
361
362<a name="reduceRight" />
363### reduceRight(arr, memo, iterator, callback)
364
365__Alias:__ foldr
366
367Same as reduce, only operates on the items in the array in reverse order.
368
369
370---------------------------------------
371
372<a name="detect" />
373### detect(arr, iterator, callback)
374
375Returns the first value in a list that passes an async truth test. The
376iterator is applied in parallel, meaning the first iterator to return true will
377fire the detect callback with that result. That means the result might not be
378the first item in the original array (in terms of order) that passes the test.
379
380If order within the original array is important then look at detectSeries.
381
382__Arguments__
383
384* arr - An array to iterate over.
385* iterator(item, callback) - A truth test to apply to each item in the array.
386 The iterator is passed a callback which must be called with a boolean argument
387 once it has completed.
388* callback(result) - A callback which is called as soon as any iterator returns
389 true, or after all the iterator functions have finished. Result will be
390 the first item in the array that passes the truth test (iterator) or the
391 value undefined if none passed.
392
393__Example__
394
395```js
396async.detect(['file1','file2','file3'], path.exists, function(result){
397 // result now equals the first file in the list that exists
398});
399```
400
401---------------------------------------
402
403<a name="detectSeries" />
404### detectSeries(arr, iterator, callback)
405
406The same as detect, only the iterator is applied to each item in the array
407in series. This means the result is always the first in the original array (in
408terms of array order) that passes the truth test.
409
410
411---------------------------------------
412
413<a name="sortBy" />
414### sortBy(arr, iterator, callback)
415
416Sorts a list by the results of running each value through an async iterator.
417
418__Arguments__
419
420* arr - An array to iterate over.
421* iterator(item, callback) - A function to apply to each item in the array.
422 The iterator is passed a callback which must be called once it has completed
423 with an error (which can be null) and a value to use as the sort criteria.
424* callback(err, results) - A callback which is called after all the iterator
425 functions have finished, or an error has occurred. Results is the items from
426 the original array sorted by the values returned by the iterator calls.
427
428__Example__
429
430```js
431async.sortBy(['file1','file2','file3'], function(file, callback){
432 fs.stat(file, function(err, stats){
433 callback(err, stats.mtime);
434 });
435}, function(err, results){
436 // results is now the original array of files sorted by
437 // modified date
438});
439```
440
441---------------------------------------
442
443<a name="some" />
444### some(arr, iterator, callback)
445
446__Alias:__ any
447
448Returns true if at least one element in the array satisfies an async test.
449_The callback for each iterator call only accepts a single argument of true or
450false, it does not accept an error argument first!_ This is in-line with the
451way node libraries work with truth tests like path.exists. Once any iterator
452call returns true, the main callback is immediately called.
453
454__Arguments__
455
456* arr - An array to iterate over.
457* iterator(item, callback) - A truth test to apply to each item in the array.
458 The iterator is passed a callback which must be called with a boolean argument
459 once it has completed.
460* callback(result) - A callback which is called as soon as any iterator returns
461 true, or after all the iterator functions have finished. Result will be
462 either true or false depending on the values of the async tests.
463
464__Example__
465
466```js
467async.some(['file1','file2','file3'], path.exists, function(result){
468 // if result is true then at least one of the files exists
469});
470```
471
472---------------------------------------
473
474<a name="every" />
475### every(arr, iterator, callback)
476
477__Alias:__ all
478
479Returns true if every element in the array satisfies an async test.
480_The callback for each iterator call only accepts a single argument of true or
481false, it does not accept an error argument first!_ This is in-line with the
482way node libraries work with truth tests like path.exists.
483
484__Arguments__
485
486* arr - An array to iterate over.
487* iterator(item, callback) - A truth test to apply to each item in the array.
488 The iterator is passed a callback which must be called with a boolean argument
489 once it has completed.
490* callback(result) - A callback which is called after all the iterator
491 functions have finished. Result will be either true or false depending on
492 the values of the async tests.
493
494__Example__
495
496```js
497async.every(['file1','file2','file3'], path.exists, function(result){
498 // if result is true then every file exists
499});
500```
501
502---------------------------------------
503
504<a name="concat" />
505### concat(arr, iterator, callback)
506
507Applies an iterator to each item in a list, concatenating the results. Returns the
508concatenated list. The iterators are called in parallel, and the results are
509concatenated as they return. There is no guarantee that the results array will
510be returned in the original order of the arguments passed to the iterator function.
511
512__Arguments__
513
514* arr - An array to iterate over
515* iterator(item, callback) - A function to apply to each item in the array.
516 The iterator is passed a callback which must be called once it has completed
517 with an error (which can be null) and an array of results.
518* callback(err, results) - A callback which is called after all the iterator
519 functions have finished, or an error has occurred. Results is an array containing
520 the concatenated results of the iterator function.
521
522__Example__
523
524```js
525async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
526 // files is now a list of filenames that exist in the 3 directories
527});
528```
529
530---------------------------------------
531
532<a name="concatSeries" />
533### concatSeries(arr, iterator, callback)
534
535Same as async.concat, but executes in series instead of parallel.
536
537
538## Control Flow
539
540<a name="series" />
541### series(tasks, [callback])
542
543Run an array of functions in series, each one running once the previous
544function has completed. If any functions in the series pass an error to its
545callback, no more functions are run and the callback for the series is
546immediately called with the value of the error. Once the tasks have completed,
547the results are passed to the final callback as an array.
548
549It is also possible to use an object instead of an array. Each property will be
550run as a function and the results will be passed to the final callback as an object
551instead of an array. This can be a more readable way of handling results from
552async.series.
553
554
555__Arguments__
556
557* tasks - An array or object containing functions to run, each function is passed
558 a callback it must call on completion.
559* callback(err, results) - An optional callback to run once all the functions
560 have completed. This function gets an array of all the arguments passed to
561 the callbacks used in the array.
562
563__Example__
564
565```js
566async.series([
567 function(callback){
568 // do some stuff ...
569 callback(null, 'one');
570 },
571 function(callback){
572 // do some more stuff ...
573 callback(null, 'two');
574 }
575],
576// optional callback
577function(err, results){
578 // results is now equal to ['one', 'two']
579});
580
581
582// an example using an object instead of an array
583async.series({
584 one: function(callback){
585 setTimeout(function(){
586 callback(null, 1);
587 }, 200);
588 },
589 two: function(callback){
590 setTimeout(function(){
591 callback(null, 2);
592 }, 100);
593 }
594},
595function(err, results) {
596 // results is now equal to: {one: 1, two: 2}
597});
598```
599
600---------------------------------------
601
602<a name="parallel" />
603### parallel(tasks, [callback])
604
605Run an array of functions in parallel, without waiting until the previous
606function has completed. If any of the functions pass an error to its
607callback, the main callback is immediately called with the value of the error.
608Once the tasks have completed, the results are passed to the final callback as an
609array.
610
611It is also possible to use an object instead of an array. Each property will be
612run as a function and the results will be passed to the final callback as an object
613instead of an array. This can be a more readable way of handling results from
614async.parallel.
615
616
617__Arguments__
618
619* tasks - An array or object containing functions to run, each function is passed a
620 callback it must call on completion.
621* callback(err, results) - An optional callback to run once all the functions
622 have completed. This function gets an array of all the arguments passed to
623 the callbacks used in the array.
624
625__Example__
626
627```js
628async.parallel([
629 function(callback){
630 setTimeout(function(){
631 callback(null, 'one');
632 }, 200);
633 },
634 function(callback){
635 setTimeout(function(){
636 callback(null, 'two');
637 }, 100);
638 }
639],
640// optional callback
641function(err, results){
642 // the results array will equal ['one','two'] even though
643 // the second function had a shorter timeout.
644});
645
646
647// an example using an object instead of an array
648async.parallel({
649 one: function(callback){
650 setTimeout(function(){
651 callback(null, 1);
652 }, 200);
653 },
654 two: function(callback){
655 setTimeout(function(){
656 callback(null, 2);
657 }, 100);
658 }
659},
660function(err, results) {
661 // results is now equals to: {one: 1, two: 2}
662});
663```
664
665---------------------------------------
666
667<a name="parallel" />
668### parallelLimit(tasks, limit, [callback])
669
670The same as parallel only the tasks are executed in parallel with a maximum of "limit"
671tasks executing at any time.
672
673__Arguments__
674
675* tasks - An array or object containing functions to run, each function is passed a
676 callback it must call on completion.
677* limit - The maximum number of tasks to run at any time.
678* callback(err, results) - An optional callback to run once all the functions
679 have completed. This function gets an array of all the arguments passed to
680 the callbacks used in the array.
681
682
683---------------------------------------
684
685<a name="whilst" />
686### whilst(test, fn, callback)
687
688Repeatedly call fn, while test returns true. Calls the callback when stopped,
689or an error occurs.
690
691__Arguments__
692
693* test() - synchronous truth test to perform before each execution of fn.
694* fn(callback) - A function to call each time the test passes. The function is
695 passed a callback which must be called once it has completed with an optional
696 error as the first argument.
697* callback(err) - A callback which is called after the test fails and repeated
698 execution of fn has stopped.
699
700__Example__
701
702```js
703var count = 0;
704
705async.whilst(
706 function () { return count < 5; },
707 function (callback) {
708 count++;
709 setTimeout(callback, 1000);
710 },
711 function (err) {
712 // 5 seconds have passed
713 }
714);
715```
716
717---------------------------------------
718
719<a name="doWhilst" />
720### doWhilst(fn, test, callback)
721
722The post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
723
724---------------------------------------
725
726<a name="until" />
727### until(test, fn, callback)
728
729Repeatedly call fn, until test returns true. Calls the callback when stopped,
730or an error occurs.
731
732The inverse of async.whilst.
733
734---------------------------------------
735
736<a name="doUntil" />
737### doUntil(fn, test, callback)
738
739Like doWhilst except the test is inverted. Note the argument ordering differs from `until`.
740
741
742---------------------------------------
743
744<a name="waterfall" />
745### waterfall(tasks, [callback])
746
747Runs an array of functions in series, each passing their results to the next in
748the array. However, if any of the functions pass an error to the callback, the
749next function is not executed and the main callback is immediately called with
750the error.
751
752__Arguments__
753
754* tasks - An array of functions to run, each function is passed a callback it
755 must call on completion.
756* callback(err, [results]) - An optional callback to run once all the functions
757 have completed. This will be passed the results of the last task's callback.
758
759
760
761__Example__
762
763```js
764async.waterfall([
765 function(callback){
766 callback(null, 'one', 'two');
767 },
768 function(arg1, arg2, callback){
769 callback(null, 'three');
770 },
771 function(arg1, callback){
772 // arg1 now equals 'three'
773 callback(null, 'done');
774 }
775], function (err, result) {
776 // result now equals 'done'
777});
778```
779
780---------------------------------------
781
782<a name="queue" />
783### queue(worker, concurrency)
784
785Creates a queue object with the specified concurrency. Tasks added to the
786queue will be processed in parallel (up to the concurrency limit). If all
787workers are in progress, the task is queued until one is available. Once
788a worker has completed a task, the task's callback is called.
789
790__Arguments__
791
792* worker(task, callback) - An asynchronous function for processing a queued
793 task.
794* concurrency - An integer for determining how many worker functions should be
795 run in parallel.
796
797__Queue objects__
798
799The queue object returned by this function has the following properties and
800methods:
801
802* length() - a function returning the number of items waiting to be processed.
803* concurrency - an integer for determining how many worker functions should be
804 run in parallel. This property can be changed after a queue is created to
805 alter the concurrency on-the-fly.
806* push(task, [callback]) - add a new task to the queue, the callback is called
807 once the worker has finished processing the task.
808 instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.
809* unshift(task, [callback]) - add a new task to the front of the queue.
810* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued
811* empty - a callback that is called when the last item from the queue is given to a worker
812* drain - a callback that is called when the last item from the queue has returned from the worker
813
814__Example__
815
816```js
817// create a queue object with concurrency 2
818
819var q = async.queue(function (task, callback) {
820 console.log('hello ' + task.name);
821 callback();
822}, 2);
823
824
825// assign a callback
826q.drain = function() {
827 console.log('all items have been processed');
828}
829
830// add some items to the queue
831
832q.push({name: 'foo'}, function (err) {
833 console.log('finished processing foo');
834});
835q.push({name: 'bar'}, function (err) {
836 console.log('finished processing bar');
837});
838
839// add some items to the queue (batch-wise)
840
841q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {
842 console.log('finished processing bar');
843});
844
845// add some items to the front of the queue
846
847q.unshift({name: 'bar'}, function (err) {
848 console.log('finished processing bar');
849});
850```
851
852---------------------------------------
853
854<a name="cargo" />
855### cargo(worker, [payload])
856
857Creates a cargo object with the specified payload. Tasks added to the
858cargo will be processed altogether (up to the payload limit). If the
859worker is in progress, the task is queued until it is available. Once
860the worker has completed some tasks, each callback of those tasks is called.
861
862__Arguments__
863
864* worker(tasks, callback) - An asynchronous function for processing queued
865 tasks.
866* payload - An optional integer for determining how many tasks should be
867 process per round, default is unlimited.
868
869__Cargo objects__
870
871The cargo object returned by this function has the following properties and
872methods:
873
874* length() - a function returning the number of items waiting to be processed.
875* payload - an integer for determining how many tasks should be
876 process per round. This property can be changed after a cargo is created to
877 alter the payload on-the-fly.
878* push(task, [callback]) - add a new task to the queue, the callback is called
879 once the worker has finished processing the task.
880 instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.
881* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued
882* empty - a callback that is called when the last item from the queue is given to a worker
883* drain - a callback that is called when the last item from the queue has returned from the worker
884
885__Example__
886
887```js
888// create a cargo object with payload 2
889
890var cargo = async.cargo(function (task, callback) {
891 console.log('hello ' + task.name);
892 callback();
893}, 2);
894
895
896// add some items
897
898cargo.push({name: 'foo'}, function (err) {
899 console.log('finished processing foo');
900});
901cargo.push({name: 'bar'}, function (err) {
902 console.log('finished processing bar');
903});
904cargo.push({name: 'baz'}, function (err) {
905 console.log('finished processing baz');
906});
907```
908
909---------------------------------------
910
911<a name="auto" />
912### auto(tasks, [callback])
913
914Determines the best order for running functions based on their requirements.
915Each function can optionally depend on other functions being completed first,
916and each function is run as soon as its requirements are satisfied. If any of
917the functions pass an error to their callback, that function will not complete
918(so any other functions depending on it will not run) and the main callback
919will be called immediately with the error. Functions also receive an object
920containing the results of functions which have completed so far.
921
922__Arguments__
923
924* tasks - An object literal containing named functions or an array of
925 requirements, with the function itself the last item in the array. The key
926 used for each function or array is used when specifying requirements. The
927 syntax is easier to understand by looking at the example.
928* callback(err, results) - An optional callback which is called when all the
929 tasks have been completed. The callback will receive an error as an argument
930 if any tasks pass an error to their callback. If all tasks complete
931 successfully, it will receive an object containing their results.
932
933__Example__
934
935```js
936async.auto({
937 get_data: function(callback){
938 // async code to get some data
939 },
940 make_folder: function(callback){
941 // async code to create a directory to store a file in
942 // this is run at the same time as getting the data
943 },
944 write_file: ['get_data', 'make_folder', function(callback){
945 // once there is some data and the directory exists,
946 // write the data to a file in the directory
947 callback(null, filename);
948 }],
949 email_link: ['write_file', function(callback, results){
950 // once the file is written let's email a link to it...
951 // results.write_file contains the filename returned by write_file.
952 }]
953});
954```
955
956This is a fairly trivial example, but to do this using the basic parallel and
957series functions would look like this:
958
959```js
960async.parallel([
961 function(callback){
962 // async code to get some data
963 },
964 function(callback){
965 // async code to create a directory to store a file in
966 // this is run at the same time as getting the data
967 }
968],
969function(err, results){
970 async.series([
971 function(callback){
972 // once there is some data and the directory exists,
973 // write the data to a file in the directory
974 },
975 function(callback){
976 // once the file is written let's email a link to it...
977 }
978 ]);
979});
980```
981
982For a complicated series of async tasks using the auto function makes adding
983new tasks much easier and makes the code more readable.
984
985
986---------------------------------------
987
988<a name="iterator" />
989### iterator(tasks)
990
991Creates an iterator function which calls the next function in the array,
992returning a continuation to call the next one after that. Its also possible to
993'peek' the next iterator by doing iterator.next().
994
995This function is used internally by the async module but can be useful when
996you want to manually control the flow of functions in series.
997
998__Arguments__
999
1000* tasks - An array of functions to run, each function is passed a callback it
1001 must call on completion.
1002
1003__Example__
1004
1005```js
1006var iterator = async.iterator([
1007 function(){ sys.p('one'); },
1008 function(){ sys.p('two'); },
1009 function(){ sys.p('three'); }
1010]);
1011
1012node> var iterator2 = iterator();
1013'one'
1014node> var iterator3 = iterator2();
1015'two'
1016node> iterator3();
1017'three'
1018node> var nextfn = iterator2.next();
1019node> nextfn();
1020'three'
1021```
1022
1023---------------------------------------
1024
1025<a name="apply" />
1026### apply(function, arguments..)
1027
1028Creates a continuation function with some arguments already applied, a useful
1029shorthand when combined with other control flow functions. Any arguments
1030passed to the returned function are added to the arguments originally passed
1031to apply.
1032
1033__Arguments__
1034
1035* function - The function you want to eventually apply all arguments to.
1036* arguments... - Any number of arguments to automatically apply when the
1037 continuation is called.
1038
1039__Example__
1040
1041```js
1042// using apply
1043
1044async.parallel([
1045 async.apply(fs.writeFile, 'testfile1', 'test1'),
1046 async.apply(fs.writeFile, 'testfile2', 'test2'),
1047]);
1048
1049
1050// the same process without using apply
1051
1052async.parallel([
1053 function(callback){
1054 fs.writeFile('testfile1', 'test1', callback);
1055 },
1056 function(callback){
1057 fs.writeFile('testfile2', 'test2', callback);
1058 }
1059]);
1060```
1061
1062It's possible to pass any number of additional arguments when calling the
1063continuation:
1064
1065```js
1066node> var fn = async.apply(sys.puts, 'one');
1067node> fn('two', 'three');
1068one
1069two
1070three
1071```
1072
1073---------------------------------------
1074
1075<a name="nextTick" />
1076### nextTick(callback)
1077
1078Calls the callback on a later loop around the event loop. In node.js this just
1079calls process.nextTick, in the browser it falls back to setImmediate(callback)
1080if available, otherwise setTimeout(callback, 0), which means other higher priority
1081events may precede the execution of the callback.
1082
1083This is used internally for browser-compatibility purposes.
1084
1085__Arguments__
1086
1087* callback - The function to call on a later loop around the event loop.
1088
1089__Example__
1090
1091```js
1092var call_order = [];
1093async.nextTick(function(){
1094 call_order.push('two');
1095 // call_order now equals ['one','two']
1096});
1097call_order.push('one')
1098```
1099
1100<a name="times" />
1101### times(n, callback)
1102
1103Calls the callback n times and accumulates results in the same manner
1104you would use with async.map.
1105
1106__Arguments__
1107
1108* n - The number of times to run the function.
1109* callback - The function to call n times.
1110
1111__Example__
1112
1113```js
1114// Pretend this is some complicated async factory
1115var createUser = function(id, callback) {
1116 callback(null, {
1117 id: 'user' + id
1118 })
1119}
1120// generate 5 users
1121async.times(5, function(n, next){
1122 createUser(n, function(err, user) {
1123 next(err, user)
1124 })
1125}, function(err, users) {
1126 // we should now have 5 users
1127});
1128```
1129
1130<a name="timesSeries" />
1131### timesSeries(n, callback)
1132
1133The same as times only the iterator is applied to each item in the array in
1134series. The next iterator is only called once the current one has completed
1135processing. The results array will be in the same order as the original.
1136
1137
1138## Utils
1139
1140<a name="memoize" />
1141### memoize(fn, [hasher])
1142
1143Caches the results of an async function. When creating a hash to store function
1144results against, the callback is omitted from the hash and an optional hash
1145function can be used.
1146
1147The cache of results is exposed as the `memo` property of the function returned
1148by `memoize`.
1149
1150__Arguments__
1151
1152* fn - the function you to proxy and cache results from.
1153* hasher - an optional function for generating a custom hash for storing
1154 results, it has all the arguments applied to it apart from the callback, and
1155 must be synchronous.
1156
1157__Example__
1158
1159```js
1160var slow_fn = function (name, callback) {
1161 // do something
1162 callback(null, result);
1163};
1164var fn = async.memoize(slow_fn);
1165
1166// fn can now be used as if it were slow_fn
1167fn('some name', function () {
1168 // callback
1169});
1170```
1171
1172<a name="unmemoize" />
1173### unmemoize(fn)
1174
1175Undoes a memoized function, reverting it to the original, unmemoized
1176form. Comes handy in tests.
1177
1178__Arguments__
1179
1180* fn - the memoized function
1181
1182<a name="log" />
1183### log(function, arguments)
1184
1185Logs the result of an async function to the console. Only works in node.js or
1186in browsers that support console.log and console.error (such as FF and Chrome).
1187If multiple arguments are returned from the async function, console.log is
1188called on each argument in order.
1189
1190__Arguments__
1191
1192* function - The function you want to eventually apply all arguments to.
1193* arguments... - Any number of arguments to apply to the function.
1194
1195__Example__
1196
1197```js
1198var hello = function(name, callback){
1199 setTimeout(function(){
1200 callback(null, 'hello ' + name);
1201 }, 1000);
1202};
1203```
1204```js
1205node> async.log(hello, 'world');
1206'hello world'
1207```
1208
1209---------------------------------------
1210
1211<a name="dir" />
1212### dir(function, arguments)
1213
1214Logs the result of an async function to the console using console.dir to
1215display the properties of the resulting object. Only works in node.js or
1216in browsers that support console.dir and console.error (such as FF and Chrome).
1217If multiple arguments are returned from the async function, console.dir is
1218called on each argument in order.
1219
1220__Arguments__
1221
1222* function - The function you want to eventually apply all arguments to.
1223* arguments... - Any number of arguments to apply to the function.
1224
1225__Example__
1226
1227```js
1228var hello = function(name, callback){
1229 setTimeout(function(){
1230 callback(null, {hello: name});
1231 }, 1000);
1232};
1233```
1234```js
1235node> async.dir(hello, 'world');
1236{hello: 'world'}
1237```
1238
1239---------------------------------------
1240
1241<a name="noConflict" />
1242### noConflict()
1243
1244Changes the value of async back to its original value, returning a reference to the
1245async object.