| OLD | NEW |
| (Empty) | |
| 1 # Async.js |
| 2 |
| 3 [](https://travis-ci.org/caolan/async) |
| 4 [](https://www.npmjs.org/pa
ckage/async) |
| 5 [](https://coveralls.io/r/caolan/async?branch=master) |
| 6 [](https://gitter.im/caolan/async?utm_source=badge&utm_medium=badge&
utm_campaign=pr-badge&utm_content=badge) |
| 7 |
| 8 |
| 9 Async is a utility module which provides straight-forward, powerful functions |
| 10 for working with asynchronous JavaScript. Although originally designed for |
| 11 use with [Node.js](http://nodejs.org) and installable via `npm install async`, |
| 12 it can also be used directly in the browser. |
| 13 |
| 14 Async is also installable via: |
| 15 |
| 16 - [bower](http://bower.io/): `bower install async` |
| 17 - [component](https://github.com/component/component): `component install |
| 18 caolan/async` |
| 19 - [jam](http://jamjs.org/): `jam install async` |
| 20 - [spm](http://spmjs.io/): `spm install async` |
| 21 |
| 22 Async provides around 20 functions that include the usual 'functional' |
| 23 suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns |
| 24 for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these |
| 25 functions assume you follow the Node.js convention of providing a single |
| 26 callback as the last argument of your `async` function. |
| 27 |
| 28 |
| 29 ## Quick Examples |
| 30 |
| 31 ```javascript |
| 32 async.map(['file1','file2','file3'], fs.stat, function(err, results){ |
| 33 // results is now an array of stats for each file |
| 34 }); |
| 35 |
| 36 async.filter(['file1','file2','file3'], fs.exists, function(results){ |
| 37 // results now equals an array of the existing files |
| 38 }); |
| 39 |
| 40 async.parallel([ |
| 41 function(){ ... }, |
| 42 function(){ ... } |
| 43 ], callback); |
| 44 |
| 45 async.series([ |
| 46 function(){ ... }, |
| 47 function(){ ... } |
| 48 ]); |
| 49 ``` |
| 50 |
| 51 There are many more functions available so take a look at the docs below for a |
| 52 full list. This module aims to be comprehensive, so if you feel anything is |
| 53 missing please create a GitHub issue for it. |
| 54 |
| 55 ## Common Pitfalls <sub>[(StackOverflow)](http://stackoverflow.com/questions/tag
ged/async.js)</sub> |
| 56 ### Synchronous iteration functions |
| 57 |
| 58 If you get an error like `RangeError: Maximum call stack size exceeded.` or othe
r stack overflow issues when using async, you are likely using a synchronous ite
rator. By *synchronous* we mean a function that calls its callback on the same
tick in the javascript event loop, without doing any I/O or using any timers. C
alling many callbacks iteratively will quickly overflow the stack. If you run in
to this issue, just defer your callback with `async.setImmediate` to start a new
call stack on the next tick of the event loop. |
| 59 |
| 60 This can also arise by accident if you callback early in certain cases: |
| 61 |
| 62 ```js |
| 63 async.eachSeries(hugeArray, function iterator(item, callback) { |
| 64 if (inCache(item)) { |
| 65 callback(null, cache[item]); // if many items are cached, you'll overflow |
| 66 } else { |
| 67 doSomeIO(item, callback); |
| 68 } |
| 69 }, function done() { |
| 70 //... |
| 71 }); |
| 72 ``` |
| 73 |
| 74 Just change it to: |
| 75 |
| 76 ```js |
| 77 async.eachSeries(hugeArray, function iterator(item, callback) { |
| 78 if (inCache(item)) { |
| 79 async.setImmediate(function () { |
| 80 callback(null, cache[item]); |
| 81 }); |
| 82 } else { |
| 83 doSomeIO(item, callback); |
| 84 //... |
| 85 ``` |
| 86 |
| 87 Async guards against synchronous functions in some, but not all, cases. If you
are still running into stack overflows, you can defer as suggested above, or wra
p functions with [`async.ensureAsync`](#ensureAsync) Functions that are asynchr
onous by their nature do not have this problem and don't need the extra callback
deferral. |
| 88 |
| 89 If JavaScript's event loop is still a bit nebulous, check out [this article](htt
p://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/) or [thi
s talk](http://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event
-loop-anyway.html) for more detailed information about how it works. |
| 90 |
| 91 |
| 92 ### Multiple callbacks |
| 93 |
| 94 Make sure to always `return` when calling a callback early, otherwise you will c
ause multiple callbacks and unpredictable behavior in many cases. |
| 95 |
| 96 ```js |
| 97 async.waterfall([ |
| 98 function (callback) { |
| 99 getSomething(options, function (err, result) { |
| 100 if (err) { |
| 101 callback(new Error("failed getting something:" + err.message)); |
| 102 // we should return here |
| 103 } |
| 104 // since we did not return, this callback still will be called and |
| 105 // `processData` will be called twice |
| 106 callback(null, result); |
| 107 }); |
| 108 }, |
| 109 processData |
| 110 ], done) |
| 111 ``` |
| 112 |
| 113 It is always good practice to `return callback(err, result)` whenever a callbac
k call is not the last statement of a function. |
| 114 |
| 115 |
| 116 ### Binding a context to an iterator |
| 117 |
| 118 This section is really about `bind`, not about `async`. If you are wondering how
to |
| 119 make `async` execute your iterators in a given context, or are confused as to wh
y |
| 120 a method of another library isn't working as an iterator, study this example: |
| 121 |
| 122 ```js |
| 123 // Here is a simple object with an (unnecessarily roundabout) squaring method |
| 124 var AsyncSquaringLibrary = { |
| 125 squareExponent: 2, |
| 126 square: function(number, callback){ |
| 127 var result = Math.pow(number, this.squareExponent); |
| 128 setTimeout(function(){ |
| 129 callback(null, result); |
| 130 }, 200); |
| 131 } |
| 132 }; |
| 133 |
| 134 async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ |
| 135 // result is [NaN, NaN, NaN] |
| 136 // This fails because the `this.squareExponent` expression in the square |
| 137 // function is not evaluated in the context of AsyncSquaringLibrary, and is |
| 138 // therefore undefined. |
| 139 }); |
| 140 |
| 141 async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), fun
ction(err, result){ |
| 142 // result is [1, 4, 9] |
| 143 // With the help of bind we can attach a context to the iterator before |
| 144 // passing it to async. Now the square function will be executed in its |
| 145 // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` |
| 146 // will be as expected. |
| 147 }); |
| 148 ``` |
| 149 |
| 150 ## Download |
| 151 |
| 152 The source is available for download from |
| 153 [GitHub](https://github.com/caolan/async/blob/master/lib/async.js). |
| 154 Alternatively, you can install using Node Package Manager (`npm`): |
| 155 |
| 156 npm install async |
| 157 |
| 158 As well as using Bower: |
| 159 |
| 160 bower install async |
| 161 |
| 162 __Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async
.js) - 29.6kb Uncompressed |
| 163 |
| 164 ## In the Browser |
| 165 |
| 166 So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. |
| 167 |
| 168 Usage: |
| 169 |
| 170 ```html |
| 171 <script type="text/javascript" src="async.js"></script> |
| 172 <script type="text/javascript"> |
| 173 |
| 174 async.map(data, asyncProcess, function(err, results){ |
| 175 alert(results); |
| 176 }); |
| 177 |
| 178 </script> |
| 179 ``` |
| 180 |
| 181 ## Documentation |
| 182 |
| 183 Some functions are also available in the following forms: |
| 184 * `<name>Series` - the same as `<name>` but runs only a single async operation a
t a time |
| 185 * `<name>Limit` - the same as `<name>` but runs a maximum of `limit` async opera
tions at a time |
| 186 |
| 187 ### Collections |
| 188 |
| 189 * [`each`](#each), `eachSeries`, `eachLimit` |
| 190 * [`forEachOf`](#forEachOf), `forEachOfSeries`, `forEachOfLimit` |
| 191 * [`map`](#map), `mapSeries`, `mapLimit` |
| 192 * [`filter`](#filter), `filterSeries`, `filterLimit` |
| 193 * [`reject`](#reject), `rejectSeries`, `rejectLimit` |
| 194 * [`reduce`](#reduce), [`reduceRight`](#reduceRight) |
| 195 * [`detect`](#detect), `detectSeries`, `detectLimit` |
| 196 * [`sortBy`](#sortBy) |
| 197 * [`some`](#some), `someLimit` |
| 198 * [`every`](#every), `everyLimit` |
| 199 * [`concat`](#concat), `concatSeries` |
| 200 |
| 201 ### Control Flow |
| 202 |
| 203 * [`series`](#seriestasks-callback) |
| 204 * [`parallel`](#parallel), `parallelLimit` |
| 205 * [`whilst`](#whilst), [`doWhilst`](#doWhilst) |
| 206 * [`until`](#until), [`doUntil`](#doUntil) |
| 207 * [`during`](#during), [`doDuring`](#doDuring) |
| 208 * [`forever`](#forever) |
| 209 * [`waterfall`](#waterfall) |
| 210 * [`compose`](#compose) |
| 211 * [`seq`](#seq) |
| 212 * [`applyEach`](#applyEach), `applyEachSeries` |
| 213 * [`queue`](#queue), [`priorityQueue`](#priorityQueue) |
| 214 * [`cargo`](#cargo) |
| 215 * [`auto`](#auto) |
| 216 * [`retry`](#retry) |
| 217 * [`iterator`](#iterator) |
| 218 * [`times`](#times), `timesSeries`, `timesLimit` |
| 219 |
| 220 ### Utils |
| 221 |
| 222 * [`apply`](#apply) |
| 223 * [`nextTick`](#nextTick) |
| 224 * [`memoize`](#memoize) |
| 225 * [`unmemoize`](#unmemoize) |
| 226 * [`ensureAsync`](#ensureAsync) |
| 227 * [`constant`](#constant) |
| 228 * [`asyncify`](#asyncify) |
| 229 * [`wrapSync`](#wrapSync) |
| 230 * [`log`](#log) |
| 231 * [`dir`](#dir) |
| 232 * [`noConflict`](#noConflict) |
| 233 |
| 234 ## Collections |
| 235 |
| 236 <a name="forEach" /> |
| 237 <a name="each" /> |
| 238 ### each(arr, iterator, [callback]) |
| 239 |
| 240 Applies the function `iterator` to each item in `arr`, in parallel. |
| 241 The `iterator` is called with an item from the list, and a callback for when it |
| 242 has finished. If the `iterator` passes an error to its `callback`, the main |
| 243 `callback` (for the `each` function) is immediately called with the error. |
| 244 |
| 245 Note, that since this function applies `iterator` to each item in parallel, |
| 246 there is no guarantee that the iterator functions will complete in order. |
| 247 |
| 248 __Arguments__ |
| 249 |
| 250 * `arr` - An array to iterate over. |
| 251 * `iterator(item, callback)` - A function to apply to each item in `arr`. |
| 252 The iterator is passed a `callback(err)` which must be called once it has |
| 253 completed. If no error has occurred, the `callback` should be run without |
| 254 arguments or with an explicit `null` argument. The array index is not passed |
| 255 to the iterator. If you need the index, use [`forEachOf`](#forEachOf). |
| 256 * `callback(err)` - *Optional* A callback which is called when all `iterator` fu
nctions |
| 257 have finished, or an error occurs. |
| 258 |
| 259 __Examples__ |
| 260 |
| 261 |
| 262 ```js |
| 263 // assuming openFiles is an array of file names and saveFile is a function |
| 264 // to save the modified contents of that file: |
| 265 |
| 266 async.each(openFiles, saveFile, function(err){ |
| 267 // if any of the saves produced an error, err would equal that error |
| 268 }); |
| 269 ``` |
| 270 |
| 271 ```js |
| 272 // assuming openFiles is an array of file names |
| 273 |
| 274 async.each(openFiles, function(file, callback) { |
| 275 |
| 276 // Perform operation on file here. |
| 277 console.log('Processing file ' + file); |
| 278 |
| 279 if( file.length > 32 ) { |
| 280 console.log('This file name is too long'); |
| 281 callback('File name too long'); |
| 282 } else { |
| 283 // Do work to process file here |
| 284 console.log('File processed'); |
| 285 callback(); |
| 286 } |
| 287 }, function(err){ |
| 288 // if any of the file processing produced an error, err would equal that err
or |
| 289 if( err ) { |
| 290 // One of the iterations produced an error. |
| 291 // All processing will now stop. |
| 292 console.log('A file failed to process'); |
| 293 } else { |
| 294 console.log('All files have been processed successfully'); |
| 295 } |
| 296 }); |
| 297 ``` |
| 298 |
| 299 __Related__ |
| 300 |
| 301 * eachSeries(arr, iterator, [callback]) |
| 302 * eachLimit(arr, limit, iterator, [callback]) |
| 303 |
| 304 --------------------------------------- |
| 305 |
| 306 <a name="forEachOf" /> |
| 307 <a name="eachOf" /> |
| 308 |
| 309 ### forEachOf(obj, iterator, [callback]) |
| 310 |
| 311 Like `each`, except that it iterates over objects, and passes the key as the sec
ond argument to the iterator. |
| 312 |
| 313 __Arguments__ |
| 314 |
| 315 * `obj` - An object or array to iterate over. |
| 316 * `iterator(item, key, callback)` - A function to apply to each item in `obj`. |
| 317 The `key` is the item's key, or index in the case of an array. The iterator is |
| 318 passed a `callback(err)` which must be called once it has completed. If no |
| 319 error has occurred, the callback should be run without arguments or with an |
| 320 explicit `null` argument. |
| 321 * `callback(err)` - *Optional* A callback which is called when all `iterator` fu
nctions have finished, or an error occurs. |
| 322 |
| 323 __Example__ |
| 324 |
| 325 ```js |
| 326 var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; |
| 327 var configs = {}; |
| 328 |
| 329 async.forEachOf(obj, function (value, key, callback) { |
| 330 fs.readFile(__dirname + value, "utf8", function (err, data) { |
| 331 if (err) return callback(err); |
| 332 try { |
| 333 configs[key] = JSON.parse(data); |
| 334 } catch (e) { |
| 335 return callback(e); |
| 336 } |
| 337 callback(); |
| 338 }) |
| 339 }, function (err) { |
| 340 if (err) console.error(err.message); |
| 341 // configs is now a map of JSON data |
| 342 doSomethingWith(configs); |
| 343 }) |
| 344 ``` |
| 345 |
| 346 __Related__ |
| 347 |
| 348 * forEachOfSeries(obj, iterator, [callback]) |
| 349 * forEachOfLimit(obj, limit, iterator, [callback]) |
| 350 |
| 351 --------------------------------------- |
| 352 |
| 353 <a name="map" /> |
| 354 ### map(arr, iterator, [callback]) |
| 355 |
| 356 Produces a new array of values by mapping each value in `arr` through |
| 357 the `iterator` function. The `iterator` is called with an item from `arr` and a |
| 358 callback for when it has finished processing. Each of these callback takes 2 arg
uments: |
| 359 an `error`, and the transformed item from `arr`. If `iterator` passes an error t
o its |
| 360 callback, the main `callback` (for the `map` function) is immediately called wit
h the error. |
| 361 |
| 362 Note, that since this function applies the `iterator` to each item in parallel, |
| 363 there is no guarantee that the `iterator` functions will complete in order. |
| 364 However, the results array will be in the same order as the original `arr`. |
| 365 |
| 366 __Arguments__ |
| 367 |
| 368 * `arr` - An array to iterate over. |
| 369 * `iterator(item, callback)` - A function to apply to each item in `arr`. |
| 370 The iterator is passed a `callback(err, transformed)` which must be called onc
e |
| 371 it has completed with an error (which can be `null`) and a transformed item. |
| 372 * `callback(err, results)` - *Optional* A callback which is called when all `ite
rator` |
| 373 functions have finished, or an error occurs. Results is an array of the |
| 374 transformed items from the `arr`. |
| 375 |
| 376 __Example__ |
| 377 |
| 378 ```js |
| 379 async.map(['file1','file2','file3'], fs.stat, function(err, results){ |
| 380 // results is now an array of stats for each file |
| 381 }); |
| 382 ``` |
| 383 |
| 384 __Related__ |
| 385 * mapSeries(arr, iterator, [callback]) |
| 386 * mapLimit(arr, limit, iterator, [callback]) |
| 387 |
| 388 --------------------------------------- |
| 389 |
| 390 <a name="select" /> |
| 391 <a name="filter" /> |
| 392 ### filter(arr, iterator, [callback]) |
| 393 |
| 394 __Alias:__ `select` |
| 395 |
| 396 Returns a new array of all the values in `arr` which pass an async truth test. |
| 397 _The callback for each `iterator` call only accepts a single argument of `true`
or |
| 398 `false`; it does not accept an error argument first!_ This is in-line with the |
| 399 way node libraries work with truth tests like `fs.exists`. This operation is |
| 400 performed in parallel, but the results array will be in the same order as the |
| 401 original. |
| 402 |
| 403 __Arguments__ |
| 404 |
| 405 * `arr` - An array to iterate over. |
| 406 * `iterator(item, callback)` - A truth test to apply to each item in `arr`. |
| 407 The `iterator` is passed a `callback(truthValue)`, which must be called with a |
| 408 boolean argument once it has completed. |
| 409 * `callback(results)` - *Optional* A callback which is called after all the `ite
rator` |
| 410 functions have finished. |
| 411 |
| 412 __Example__ |
| 413 |
| 414 ```js |
| 415 async.filter(['file1','file2','file3'], fs.exists, function(results){ |
| 416 // results now equals an array of the existing files |
| 417 }); |
| 418 ``` |
| 419 |
| 420 __Related__ |
| 421 |
| 422 * filterSeries(arr, iterator, [callback]) |
| 423 * filterLimit(arr, limit, iterator, [callback]) |
| 424 |
| 425 --------------------------------------- |
| 426 |
| 427 <a name="reject" /> |
| 428 ### reject(arr, iterator, [callback]) |
| 429 |
| 430 The opposite of [`filter`](#filter). Removes values that pass an `async` truth t
est. |
| 431 |
| 432 __Related__ |
| 433 |
| 434 * rejectSeries(arr, iterator, [callback]) |
| 435 * rejectLimit(arr, limit, iterator, [callback]) |
| 436 |
| 437 --------------------------------------- |
| 438 |
| 439 <a name="reduce" /> |
| 440 ### reduce(arr, memo, iterator, [callback]) |
| 441 |
| 442 __Aliases:__ `inject`, `foldl` |
| 443 |
| 444 Reduces `arr` into a single value using an async `iterator` to return |
| 445 each successive step. `memo` is the initial state of the reduction. |
| 446 This function only operates in series. |
| 447 |
| 448 For performance reasons, it may make sense to split a call to this function into |
| 449 a parallel map, and then use the normal `Array.prototype.reduce` on the results. |
| 450 This function is for situations where each step in the reduction needs to be asy
nc; |
| 451 if you can get the data before reducing it, then it's probably a good idea to do
so. |
| 452 |
| 453 __Arguments__ |
| 454 |
| 455 * `arr` - An array to iterate over. |
| 456 * `memo` - The initial state of the reduction. |
| 457 * `iterator(memo, item, callback)` - A function applied to each item in the |
| 458 array to produce the next step in the reduction. The `iterator` is passed a |
| 459 `callback(err, reduction)` which accepts an optional error as its first |
| 460 argument, and the state of the reduction as the second. If an error is |
| 461 passed to the callback, the reduction is stopped and the main `callback` is |
| 462 immediately called with the error. |
| 463 * `callback(err, result)` - *Optional* A callback which is called after all the
`iterator` |
| 464 functions have finished. Result is the reduced value. |
| 465 |
| 466 __Example__ |
| 467 |
| 468 ```js |
| 469 async.reduce([1,2,3], 0, function(memo, item, callback){ |
| 470 // pointless async: |
| 471 process.nextTick(function(){ |
| 472 callback(null, memo + item) |
| 473 }); |
| 474 }, function(err, result){ |
| 475 // result is now equal to the last value of memo, which is 6 |
| 476 }); |
| 477 ``` |
| 478 |
| 479 --------------------------------------- |
| 480 |
| 481 <a name="reduceRight" /> |
| 482 ### reduceRight(arr, memo, iterator, [callback]) |
| 483 |
| 484 __Alias:__ `foldr` |
| 485 |
| 486 Same as [`reduce`](#reduce), only operates on `arr` in reverse order. |
| 487 |
| 488 |
| 489 --------------------------------------- |
| 490 |
| 491 <a name="detect" /> |
| 492 ### detect(arr, iterator, [callback]) |
| 493 |
| 494 Returns the first value in `arr` that passes an async truth test. The |
| 495 `iterator` is applied in parallel, meaning the first iterator to return `true` w
ill |
| 496 fire the detect `callback` with that result. That means the result might not be |
| 497 the first item in the original `arr` (in terms of order) that passes the test. |
| 498 |
| 499 If order within the original `arr` is important, then look at [`detectSeries`](#
detectSeries). |
| 500 |
| 501 __Arguments__ |
| 502 |
| 503 * `arr` - An array to iterate over. |
| 504 * `iterator(item, callback)` - A truth test to apply to each item in `arr`. |
| 505 The iterator is passed a `callback(truthValue)` which must be called with a |
| 506 boolean argument once it has completed. **Note: this callback does not take an
error as its first argument.** |
| 507 * `callback(result)` - *Optional* A callback which is called as soon as any iter
ator returns |
| 508 `true`, or after all the `iterator` functions have finished. Result will be |
| 509 the first item in the array that passes the truth test (iterator) or the |
| 510 value `undefined` if none passed. **Note: this callback does not take an erro
r as its first argument.** |
| 511 |
| 512 __Example__ |
| 513 |
| 514 ```js |
| 515 async.detect(['file1','file2','file3'], fs.exists, function(result){ |
| 516 // result now equals the first file in the list that exists |
| 517 }); |
| 518 ``` |
| 519 |
| 520 __Related__ |
| 521 |
| 522 * detectSeries(arr, iterator, [callback]) |
| 523 * detectLimit(arr, limit, iterator, [callback]) |
| 524 |
| 525 --------------------------------------- |
| 526 |
| 527 <a name="sortBy" /> |
| 528 ### sortBy(arr, iterator, [callback]) |
| 529 |
| 530 Sorts a list by the results of running each `arr` value through an async `iterat
or`. |
| 531 |
| 532 __Arguments__ |
| 533 |
| 534 * `arr` - An array to iterate over. |
| 535 * `iterator(item, callback)` - A function to apply to each item in `arr`. |
| 536 The iterator is passed a `callback(err, sortValue)` which must be called once
it |
| 537 has completed with an error (which can be `null`) and a value to use as the so
rt |
| 538 criteria. |
| 539 * `callback(err, results)` - *Optional* A callback which is called after all the
`iterator` |
| 540 functions have finished, or an error occurs. Results is the items from |
| 541 the original `arr` sorted by the values returned by the `iterator` calls. |
| 542 |
| 543 __Example__ |
| 544 |
| 545 ```js |
| 546 async.sortBy(['file1','file2','file3'], function(file, callback){ |
| 547 fs.stat(file, function(err, stats){ |
| 548 callback(err, stats.mtime); |
| 549 }); |
| 550 }, function(err, results){ |
| 551 // results is now the original array of files sorted by |
| 552 // modified date |
| 553 }); |
| 554 ``` |
| 555 |
| 556 __Sort Order__ |
| 557 |
| 558 By modifying the callback parameter the sorting order can be influenced: |
| 559 |
| 560 ```js |
| 561 //ascending order |
| 562 async.sortBy([1,9,3,5], function(x, callback){ |
| 563 callback(null, x); |
| 564 }, function(err,result){ |
| 565 //result callback |
| 566 } ); |
| 567 |
| 568 //descending order |
| 569 async.sortBy([1,9,3,5], function(x, callback){ |
| 570 callback(null, x*-1); //<- x*-1 instead of x, turns the order around |
| 571 }, function(err,result){ |
| 572 //result callback |
| 573 } ); |
| 574 ``` |
| 575 |
| 576 --------------------------------------- |
| 577 |
| 578 <a name="some" /> |
| 579 ### some(arr, iterator, [callback]) |
| 580 |
| 581 __Alias:__ `any` |
| 582 |
| 583 Returns `true` if at least one element in the `arr` satisfies an async test. |
| 584 _The callback for each iterator call only accepts a single argument of `true` or |
| 585 `false`; it does not accept an error argument first!_ This is in-line with the |
| 586 way node libraries work with truth tests like `fs.exists`. Once any iterator |
| 587 call returns `true`, the main `callback` is immediately called. |
| 588 |
| 589 __Arguments__ |
| 590 |
| 591 * `arr` - An array to iterate over. |
| 592 * `iterator(item, callback)` - A truth test to apply to each item in the array |
| 593 in parallel. The iterator is passed a `callback(truthValue)`` which must be |
| 594 called with a boolean argument once it has completed. |
| 595 * `callback(result)` - *Optional* A callback which is called as soon as any iter
ator returns |
| 596 `true`, or after all the iterator functions have finished. Result will be |
| 597 either `true` or `false` depending on the values of the async tests. |
| 598 |
| 599 **Note: the callbacks do not take an error as their first argument.** |
| 600 __Example__ |
| 601 |
| 602 ```js |
| 603 async.some(['file1','file2','file3'], fs.exists, function(result){ |
| 604 // if result is true then at least one of the files exists |
| 605 }); |
| 606 ``` |
| 607 |
| 608 __Related__ |
| 609 |
| 610 * someLimit(arr, limit, iterator, callback) |
| 611 |
| 612 --------------------------------------- |
| 613 |
| 614 <a name="every" /> |
| 615 ### every(arr, iterator, [callback]) |
| 616 |
| 617 __Alias:__ `all` |
| 618 |
| 619 Returns `true` if every element in `arr` satisfies an async test. |
| 620 _The callback for each `iterator` call only accepts a single argument of `true`
or |
| 621 `false`; it does not accept an error argument first!_ This is in-line with the |
| 622 way node libraries work with truth tests like `fs.exists`. |
| 623 |
| 624 __Arguments__ |
| 625 |
| 626 * `arr` - An array to iterate over. |
| 627 * `iterator(item, callback)` - A truth test to apply to each item in the array |
| 628 in parallel. The iterator is passed a `callback(truthValue)` which must be |
| 629 called with a boolean argument once it has completed. |
| 630 * `callback(result)` - *Optional* A callback which is called as soon as any iter
ator returns |
| 631 `false`, or after all the iterator functions have finished. Result will be |
| 632 either `true` or `false` depending on the values of the async tests. |
| 633 |
| 634 **Note: the callbacks do not take an error as their first argument.** |
| 635 |
| 636 __Example__ |
| 637 |
| 638 ```js |
| 639 async.every(['file1','file2','file3'], fs.exists, function(result){ |
| 640 // if result is true then every file exists |
| 641 }); |
| 642 ``` |
| 643 |
| 644 __Related__ |
| 645 |
| 646 * everyLimit(arr, limit, iterator, callback) |
| 647 |
| 648 --------------------------------------- |
| 649 |
| 650 <a name="concat" /> |
| 651 ### concat(arr, iterator, [callback]) |
| 652 |
| 653 Applies `iterator` to each item in `arr`, concatenating the results. Returns the |
| 654 concatenated list. The `iterator`s are called in parallel, and the results are |
| 655 concatenated as they return. There is no guarantee that the results array will |
| 656 be returned in the original order of `arr` passed to the `iterator` function. |
| 657 |
| 658 __Arguments__ |
| 659 |
| 660 * `arr` - An array to iterate over. |
| 661 * `iterator(item, callback)` - A function to apply to each item in `arr`. |
| 662 The iterator is passed a `callback(err, results)` which must be called once it |
| 663 has completed with an error (which can be `null`) and an array of results. |
| 664 * `callback(err, results)` - *Optional* A callback which is called after all the
`iterator` |
| 665 functions have finished, or an error occurs. Results is an array containing |
| 666 the concatenated results of the `iterator` function. |
| 667 |
| 668 __Example__ |
| 669 |
| 670 ```js |
| 671 async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ |
| 672 // files is now a list of filenames that exist in the 3 directories |
| 673 }); |
| 674 ``` |
| 675 |
| 676 __Related__ |
| 677 |
| 678 * concatSeries(arr, iterator, [callback]) |
| 679 |
| 680 |
| 681 ## Control Flow |
| 682 |
| 683 <a name="series" /> |
| 684 ### series(tasks, [callback]) |
| 685 |
| 686 Run the functions in the `tasks` array in series, each one running once the prev
ious |
| 687 function has completed. If any functions in the series pass an error to its |
| 688 callback, no more functions are run, and `callback` is immediately called with t
he value of the error. |
| 689 Otherwise, `callback` receives an array of results when `tasks` have completed. |
| 690 |
| 691 It is also possible to use an object instead of an array. Each property will be |
| 692 run as a function, and the results will be passed to the final `callback` as an
object |
| 693 instead of an array. This can be a more readable way of handling results from |
| 694 [`series`](#series). |
| 695 |
| 696 **Note** that while many implementations preserve the order of object properties
, the |
| 697 [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5
.1/#sec-8.6) |
| 698 explicitly states that |
| 699 |
| 700 > The mechanics and order of enumerating the properties is not specified. |
| 701 |
| 702 So if you rely on the order in which your series of functions are executed, and
want |
| 703 this to work on all platforms, consider using an array. |
| 704 |
| 705 __Arguments__ |
| 706 |
| 707 * `tasks` - An array or object containing functions to run, each function is pas
sed |
| 708 a `callback(err, result)` it must call on completion with an error `err` (whic
h can |
| 709 be `null`) and an optional `result` value. |
| 710 * `callback(err, results)` - An optional callback to run once all the functions |
| 711 have completed. This function gets a results array (or object) containing all |
| 712 the result arguments passed to the `task` callbacks. |
| 713 |
| 714 __Example__ |
| 715 |
| 716 ```js |
| 717 async.series([ |
| 718 function(callback){ |
| 719 // do some stuff ... |
| 720 callback(null, 'one'); |
| 721 }, |
| 722 function(callback){ |
| 723 // do some more stuff ... |
| 724 callback(null, 'two'); |
| 725 } |
| 726 ], |
| 727 // optional callback |
| 728 function(err, results){ |
| 729 // results is now equal to ['one', 'two'] |
| 730 }); |
| 731 |
| 732 |
| 733 // an example using an object instead of an array |
| 734 async.series({ |
| 735 one: function(callback){ |
| 736 setTimeout(function(){ |
| 737 callback(null, 1); |
| 738 }, 200); |
| 739 }, |
| 740 two: function(callback){ |
| 741 setTimeout(function(){ |
| 742 callback(null, 2); |
| 743 }, 100); |
| 744 } |
| 745 }, |
| 746 function(err, results) { |
| 747 // results is now equal to: {one: 1, two: 2} |
| 748 }); |
| 749 ``` |
| 750 |
| 751 --------------------------------------- |
| 752 |
| 753 <a name="parallel" /> |
| 754 ### parallel(tasks, [callback]) |
| 755 |
| 756 Run the `tasks` array of functions in parallel, without waiting until the previo
us |
| 757 function has completed. If any of the functions pass an error to its |
| 758 callback, the main `callback` is immediately called with the value of the error. |
| 759 Once the `tasks` have completed, the results are passed to the final `callback`
as an |
| 760 array. |
| 761 |
| 762 **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about paral
lel execution of code. If your tasks do not use any timers or perform any I/O,
they will actually be executed in series. Any synchronous setup sections for ea
ch task will happen one after the other. JavaScript remains single-threaded. |
| 763 |
| 764 It is also possible to use an object instead of an array. Each property will be |
| 765 run as a function and the results will be passed to the final `callback` as an o
bject |
| 766 instead of an array. This can be a more readable way of handling results from |
| 767 [`parallel`](#parallel). |
| 768 |
| 769 |
| 770 __Arguments__ |
| 771 |
| 772 * `tasks` - An array or object containing functions to run. Each function is pas
sed |
| 773 a `callback(err, result)` which it must call on completion with an error `err` |
| 774 (which can be `null`) and an optional `result` value. |
| 775 * `callback(err, results)` - An optional callback to run once all the functions |
| 776 have completed successfully. This function gets a results array (or object) co
ntaining all |
| 777 the result arguments passed to the task callbacks. |
| 778 |
| 779 __Example__ |
| 780 |
| 781 ```js |
| 782 async.parallel([ |
| 783 function(callback){ |
| 784 setTimeout(function(){ |
| 785 callback(null, 'one'); |
| 786 }, 200); |
| 787 }, |
| 788 function(callback){ |
| 789 setTimeout(function(){ |
| 790 callback(null, 'two'); |
| 791 }, 100); |
| 792 } |
| 793 ], |
| 794 // optional callback |
| 795 function(err, results){ |
| 796 // the results array will equal ['one','two'] even though |
| 797 // the second function had a shorter timeout. |
| 798 }); |
| 799 |
| 800 |
| 801 // an example using an object instead of an array |
| 802 async.parallel({ |
| 803 one: function(callback){ |
| 804 setTimeout(function(){ |
| 805 callback(null, 1); |
| 806 }, 200); |
| 807 }, |
| 808 two: function(callback){ |
| 809 setTimeout(function(){ |
| 810 callback(null, 2); |
| 811 }, 100); |
| 812 } |
| 813 }, |
| 814 function(err, results) { |
| 815 // results is now equals to: {one: 1, two: 2} |
| 816 }); |
| 817 ``` |
| 818 |
| 819 __Related__ |
| 820 |
| 821 * parallelLimit(tasks, limit, [callback]) |
| 822 |
| 823 --------------------------------------- |
| 824 |
| 825 <a name="whilst" /> |
| 826 ### whilst(test, fn, callback) |
| 827 |
| 828 Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped
, |
| 829 or an error occurs. |
| 830 |
| 831 __Arguments__ |
| 832 |
| 833 * `test()` - synchronous truth test to perform before each execution of `fn`. |
| 834 * `fn(callback)` - A function which is called each time `test` passes. The funct
ion is |
| 835 passed a `callback(err)`, which must be called once it has completed with an |
| 836 optional `err` argument. |
| 837 * `callback(err, [results])` - A callback which is called after the test |
| 838 function has failed and repeated execution of `fn` has stopped. `callback` |
| 839 will be passed an error and any arguments passed to the final `fn`'s callback. |
| 840 |
| 841 __Example__ |
| 842 |
| 843 ```js |
| 844 var count = 0; |
| 845 |
| 846 async.whilst( |
| 847 function () { return count < 5; }, |
| 848 function (callback) { |
| 849 count++; |
| 850 setTimeout(function () { |
| 851 callback(null, count); |
| 852 }, 1000); |
| 853 }, |
| 854 function (err, n) { |
| 855 // 5 seconds have passed, n = 5 |
| 856 } |
| 857 ); |
| 858 ``` |
| 859 |
| 860 --------------------------------------- |
| 861 |
| 862 <a name="doWhilst" /> |
| 863 ### doWhilst(fn, test, callback) |
| 864 |
| 865 The post-check version of [`whilst`](#whilst). To reflect the difference in |
| 866 the order of operations, the arguments `test` and `fn` are switched. |
| 867 |
| 868 `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. |
| 869 |
| 870 --------------------------------------- |
| 871 |
| 872 <a name="until" /> |
| 873 ### until(test, fn, callback) |
| 874 |
| 875 Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, |
| 876 or an error occurs. `callback` will be passed an error and any arguments passed |
| 877 to the final `fn`'s callback. |
| 878 |
| 879 The inverse of [`whilst`](#whilst). |
| 880 |
| 881 --------------------------------------- |
| 882 |
| 883 <a name="doUntil" /> |
| 884 ### doUntil(fn, test, callback) |
| 885 |
| 886 Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument o
rdering differs from `until`. |
| 887 |
| 888 --------------------------------------- |
| 889 |
| 890 <a name="during" /> |
| 891 ### during(test, fn, callback) |
| 892 |
| 893 Like [`whilst`](#whilst), except the `test` is an asynchronous function that is
passed a callback in the form of `function (err, truth)`. If error is passed to
`test` or `fn`, the main callback is immediately called with the value of the er
ror. |
| 894 |
| 895 __Example__ |
| 896 |
| 897 ```js |
| 898 var count = 0; |
| 899 |
| 900 async.during( |
| 901 function (callback) { |
| 902 return callback(null, count < 5); |
| 903 }, |
| 904 function (callback) { |
| 905 count++; |
| 906 setTimeout(callback, 1000); |
| 907 }, |
| 908 function (err) { |
| 909 // 5 seconds have passed |
| 910 } |
| 911 ); |
| 912 ``` |
| 913 |
| 914 --------------------------------------- |
| 915 |
| 916 <a name="doDuring" /> |
| 917 ### doDuring(fn, test, callback) |
| 918 |
| 919 The post-check version of [`during`](#during). To reflect the difference in |
| 920 the order of operations, the arguments `test` and `fn` are switched. |
| 921 |
| 922 Also a version of [`doWhilst`](#doWhilst) with asynchronous `test` function. |
| 923 |
| 924 --------------------------------------- |
| 925 |
| 926 <a name="forever" /> |
| 927 ### forever(fn, [errback]) |
| 928 |
| 929 Calls the asynchronous function `fn` with a callback parameter that allows it to |
| 930 call itself again, in series, indefinitely. |
| 931 |
| 932 If an error is passed to the callback then `errback` is called with the |
| 933 error, and execution stops, otherwise it will never be called. |
| 934 |
| 935 ```js |
| 936 async.forever( |
| 937 function(next) { |
| 938 // next is suitable for passing to things that need a callback(err [, wh
atever]); |
| 939 // it will result in this function being called again. |
| 940 }, |
| 941 function(err) { |
| 942 // if next is called with a value in its first parameter, it will appear |
| 943 // in here as 'err', and execution will stop. |
| 944 } |
| 945 ); |
| 946 ``` |
| 947 |
| 948 --------------------------------------- |
| 949 |
| 950 <a name="waterfall" /> |
| 951 ### waterfall(tasks, [callback]) |
| 952 |
| 953 Runs the `tasks` array of functions in series, each passing their results to the
next in |
| 954 the array. However, if any of the `tasks` pass an error to their own callback, t
he |
| 955 next function is not executed, and the main `callback` is immediately called wit
h |
| 956 the error. |
| 957 |
| 958 __Arguments__ |
| 959 |
| 960 * `tasks` - An array of functions to run, each function is passed a |
| 961 `callback(err, result1, result2, ...)` it must call on completion. The first |
| 962 argument is an error (which can be `null`) and any further arguments will be |
| 963 passed as arguments in order to the next task. |
| 964 * `callback(err, [results])` - An optional callback to run once all the function
s |
| 965 have completed. This will be passed the results of the last task's callback. |
| 966 |
| 967 |
| 968 |
| 969 __Example__ |
| 970 |
| 971 ```js |
| 972 async.waterfall([ |
| 973 function(callback) { |
| 974 callback(null, 'one', 'two'); |
| 975 }, |
| 976 function(arg1, arg2, callback) { |
| 977 // arg1 now equals 'one' and arg2 now equals 'two' |
| 978 callback(null, 'three'); |
| 979 }, |
| 980 function(arg1, callback) { |
| 981 // arg1 now equals 'three' |
| 982 callback(null, 'done'); |
| 983 } |
| 984 ], function (err, result) { |
| 985 // result now equals 'done' |
| 986 }); |
| 987 ``` |
| 988 Or, with named functions: |
| 989 |
| 990 ```js |
| 991 async.waterfall([ |
| 992 myFirstFunction, |
| 993 mySecondFunction, |
| 994 myLastFunction, |
| 995 ], function (err, result) { |
| 996 // result now equals 'done' |
| 997 }); |
| 998 function myFirstFunction(callback) { |
| 999 callback(null, 'one', 'two'); |
| 1000 } |
| 1001 function mySecondFunction(arg1, arg2, callback) { |
| 1002 // arg1 now equals 'one' and arg2 now equals 'two' |
| 1003 callback(null, 'three'); |
| 1004 } |
| 1005 function myLastFunction(arg1, callback) { |
| 1006 // arg1 now equals 'three' |
| 1007 callback(null, 'done'); |
| 1008 } |
| 1009 ``` |
| 1010 |
| 1011 Or, if you need to pass any argument to the first function: |
| 1012 |
| 1013 ```js |
| 1014 async.waterfall([ |
| 1015 async.apply(myFirstFunction, 'zero'), |
| 1016 mySecondFunction, |
| 1017 myLastFunction, |
| 1018 ], function (err, result) { |
| 1019 // result now equals 'done' |
| 1020 }); |
| 1021 function myFirstFunction(arg1, callback) { |
| 1022 // arg1 now equals 'zero' |
| 1023 callback(null, 'one', 'two'); |
| 1024 } |
| 1025 function mySecondFunction(arg1, arg2, callback) { |
| 1026 // arg1 now equals 'one' and arg2 now equals 'two' |
| 1027 callback(null, 'three'); |
| 1028 } |
| 1029 function myLastFunction(arg1, callback) { |
| 1030 // arg1 now equals 'three' |
| 1031 callback(null, 'done'); |
| 1032 } |
| 1033 ``` |
| 1034 |
| 1035 --------------------------------------- |
| 1036 <a name="compose" /> |
| 1037 ### compose(fn1, fn2...) |
| 1038 |
| 1039 Creates a function which is a composition of the passed asynchronous |
| 1040 functions. Each function consumes the return value of the function that |
| 1041 follows. Composing functions `f()`, `g()`, and `h()` would produce the result of |
| 1042 `f(g(h()))`, only this version uses callbacks to obtain the return values. |
| 1043 |
| 1044 Each function is executed with the `this` binding of the composed function. |
| 1045 |
| 1046 __Arguments__ |
| 1047 |
| 1048 * `functions...` - the asynchronous functions to compose |
| 1049 |
| 1050 |
| 1051 __Example__ |
| 1052 |
| 1053 ```js |
| 1054 function add1(n, callback) { |
| 1055 setTimeout(function () { |
| 1056 callback(null, n + 1); |
| 1057 }, 10); |
| 1058 } |
| 1059 |
| 1060 function mul3(n, callback) { |
| 1061 setTimeout(function () { |
| 1062 callback(null, n * 3); |
| 1063 }, 10); |
| 1064 } |
| 1065 |
| 1066 var add1mul3 = async.compose(mul3, add1); |
| 1067 |
| 1068 add1mul3(4, function (err, result) { |
| 1069 // result now equals 15 |
| 1070 }); |
| 1071 ``` |
| 1072 |
| 1073 --------------------------------------- |
| 1074 <a name="seq" /> |
| 1075 ### seq(fn1, fn2...) |
| 1076 |
| 1077 Version of the compose function that is more natural to read. |
| 1078 Each function consumes the return value of the previous function. |
| 1079 It is the equivalent of [`compose`](#compose) with the arguments reversed. |
| 1080 |
| 1081 Each function is executed with the `this` binding of the composed function. |
| 1082 |
| 1083 __Arguments__ |
| 1084 |
| 1085 * `functions...` - the asynchronous functions to compose |
| 1086 |
| 1087 |
| 1088 __Example__ |
| 1089 |
| 1090 ```js |
| 1091 // Requires lodash (or underscore), express3 and dresende's orm2. |
| 1092 // Part of an app, that fetches cats of the logged user. |
| 1093 // This example uses `seq` function to avoid overnesting and error |
| 1094 // handling clutter. |
| 1095 app.get('/cats', function(request, response) { |
| 1096 var User = request.models.User; |
| 1097 async.seq( |
| 1098 _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data
)) |
| 1099 function(user, fn) { |
| 1100 user.getCats(fn); // 'getCats' has signature (callback(err, data)) |
| 1101 } |
| 1102 )(req.session.user_id, function (err, cats) { |
| 1103 if (err) { |
| 1104 console.error(err); |
| 1105 response.json({ status: 'error', message: err.message }); |
| 1106 } else { |
| 1107 response.json({ status: 'ok', message: 'Cats found', data: cats }); |
| 1108 } |
| 1109 }); |
| 1110 }); |
| 1111 ``` |
| 1112 |
| 1113 --------------------------------------- |
| 1114 <a name="applyEach" /> |
| 1115 ### applyEach(fns, args..., callback) |
| 1116 |
| 1117 Applies the provided arguments to each function in the array, calling |
| 1118 `callback` after all functions have completed. If you only provide the first |
| 1119 argument, then it will return a function which lets you pass in the |
| 1120 arguments as if it were a single function call. |
| 1121 |
| 1122 __Arguments__ |
| 1123 |
| 1124 * `fns` - the asynchronous functions to all call with the same arguments |
| 1125 * `args...` - any number of separate arguments to pass to the function |
| 1126 * `callback` - the final argument should be the callback, called when all |
| 1127 functions have completed processing |
| 1128 |
| 1129 |
| 1130 __Example__ |
| 1131 |
| 1132 ```js |
| 1133 async.applyEach([enableSearch, updateSchema], 'bucket', callback); |
| 1134 |
| 1135 // partial application example: |
| 1136 async.each( |
| 1137 buckets, |
| 1138 async.applyEach([enableSearch, updateSchema]), |
| 1139 callback |
| 1140 ); |
| 1141 ``` |
| 1142 |
| 1143 __Related__ |
| 1144 |
| 1145 * applyEachSeries(tasks, args..., [callback]) |
| 1146 |
| 1147 --------------------------------------- |
| 1148 |
| 1149 <a name="queue" /> |
| 1150 ### queue(worker, [concurrency]) |
| 1151 |
| 1152 Creates a `queue` object with the specified `concurrency`. Tasks added to the |
| 1153 `queue` are processed in parallel (up to the `concurrency` limit). If all |
| 1154 `worker`s are in progress, the task is queued until one becomes available. |
| 1155 Once a `worker` completes a `task`, that `task`'s callback is called. |
| 1156 |
| 1157 __Arguments__ |
| 1158 |
| 1159 * `worker(task, callback)` - An asynchronous function for processing a queued |
| 1160 task, which must call its `callback(err)` argument when finished, with an |
| 1161 optional `error` as an argument. If you want to handle errors from an individ
ual task, pass a callback to `q.push()`. |
| 1162 * `concurrency` - An `integer` for determining how many `worker` functions shoul
d be |
| 1163 run in parallel. If omitted, the concurrency defaults to `1`. If the concurr
ency is `0`, an error is thrown. |
| 1164 |
| 1165 __Queue objects__ |
| 1166 |
| 1167 The `queue` object returned by this function has the following properties and |
| 1168 methods: |
| 1169 |
| 1170 * `length()` - a function returning the number of items waiting to be processed. |
| 1171 * `started` - a function returning whether or not any items have been pushed and
processed by the queue |
| 1172 * `running()` - a function returning the number of items currently being process
ed. |
| 1173 * `workersList()` - a function returning the array of items currently being proc
essed. |
| 1174 * `idle()` - a function returning false if there are items waiting or being proc
essed, or true if not. |
| 1175 * `concurrency` - an integer for determining how many `worker` functions should
be |
| 1176 run in parallel. This property can be changed after a `queue` is created to |
| 1177 alter the concurrency on-the-fly. |
| 1178 * `push(task, [callback])` - add a new task to the `queue`. Calls `callback` onc
e |
| 1179 the `worker` has finished processing the task. Instead of a single task, a `ta
sks` array |
| 1180 can be submitted. The respective callback is used for every task in the list. |
| 1181 * `unshift(task, [callback])` - add a new task to the front of the `queue`. |
| 1182 * `saturated` - a callback that is called when the `queue` length hits the `conc
urrency` limit, |
| 1183 and further tasks will be queued. |
| 1184 * `empty` - a callback that is called when the last item from the `queue` is giv
en to a `worker`. |
| 1185 * `drain` - a callback that is called when the last item from the `queue` has re
turned from the `worker`. |
| 1186 * `paused` - a boolean for determining whether the queue is in a paused state |
| 1187 * `pause()` - a function that pauses the processing of tasks until `resume()` is
called. |
| 1188 * `resume()` - a function that resumes the processing of queued tasks when the q
ueue is paused. |
| 1189 * `kill()` - a function that removes the `drain` callback and empties remaining
tasks from the queue forcing it to go idle. |
| 1190 |
| 1191 __Example__ |
| 1192 |
| 1193 ```js |
| 1194 // create a queue object with concurrency 2 |
| 1195 |
| 1196 var q = async.queue(function (task, callback) { |
| 1197 console.log('hello ' + task.name); |
| 1198 callback(); |
| 1199 }, 2); |
| 1200 |
| 1201 |
| 1202 // assign a callback |
| 1203 q.drain = function() { |
| 1204 console.log('all items have been processed'); |
| 1205 } |
| 1206 |
| 1207 // add some items to the queue |
| 1208 |
| 1209 q.push({name: 'foo'}, function (err) { |
| 1210 console.log('finished processing foo'); |
| 1211 }); |
| 1212 q.push({name: 'bar'}, function (err) { |
| 1213 console.log('finished processing bar'); |
| 1214 }); |
| 1215 |
| 1216 // add some items to the queue (batch-wise) |
| 1217 |
| 1218 q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { |
| 1219 console.log('finished processing item'); |
| 1220 }); |
| 1221 |
| 1222 // add some items to the front of the queue |
| 1223 |
| 1224 q.unshift({name: 'bar'}, function (err) { |
| 1225 console.log('finished processing bar'); |
| 1226 }); |
| 1227 ``` |
| 1228 |
| 1229 |
| 1230 --------------------------------------- |
| 1231 |
| 1232 <a name="priorityQueue" /> |
| 1233 ### priorityQueue(worker, concurrency) |
| 1234 |
| 1235 The same as [`queue`](#queue) only tasks are assigned a priority and completed i
n ascending priority order. There are two differences between `queue` and `prior
ityQueue` objects: |
| 1236 |
| 1237 * `push(task, priority, [callback])` - `priority` should be a number. If an arra
y of |
| 1238 `tasks` is given, all tasks will be assigned the same priority. |
| 1239 * The `unshift` method was removed. |
| 1240 |
| 1241 --------------------------------------- |
| 1242 |
| 1243 <a name="cargo" /> |
| 1244 ### cargo(worker, [payload]) |
| 1245 |
| 1246 Creates a `cargo` object with the specified payload. Tasks added to the |
| 1247 cargo will be processed altogether (up to the `payload` limit). If the |
| 1248 `worker` is in progress, the task is queued until it becomes available. Once |
| 1249 the `worker` has completed some tasks, each callback of those tasks is called. |
| 1250 Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e
97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f617373657473
2f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d33
33393763363464633835382e676966) [animations](https://camo.githubusercontent.com/
f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746
875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d35663
2392d313165322d383134662d3964336430323431336266642e676966) for how `cargo` and `
queue` work. |
| 1251 |
| 1252 While [queue](#queue) passes only one task to one of a group of workers |
| 1253 at a time, cargo passes an array of tasks to a single worker, repeating |
| 1254 when the worker is finished. |
| 1255 |
| 1256 __Arguments__ |
| 1257 |
| 1258 * `worker(tasks, callback)` - An asynchronous function for processing an array o
f |
| 1259 queued tasks, which must call its `callback(err)` argument when finished, with |
| 1260 an optional `err` argument. |
| 1261 * `payload` - An optional `integer` for determining how many tasks should be |
| 1262 processed per round; if omitted, the default is unlimited. |
| 1263 |
| 1264 __Cargo objects__ |
| 1265 |
| 1266 The `cargo` object returned by this function has the following properties and |
| 1267 methods: |
| 1268 |
| 1269 * `length()` - A function returning the number of items waiting to be processed. |
| 1270 * `payload` - An `integer` for determining how many tasks should be |
| 1271 process per round. This property can be changed after a `cargo` is created to |
| 1272 alter the payload on-the-fly. |
| 1273 * `push(task, [callback])` - Adds `task` to the `queue`. The callback is called |
| 1274 once the `worker` has finished processing the task. Instead of a single task,
an array of `tasks` |
| 1275 can be submitted. The respective callback is used for every task in the list. |
| 1276 * `saturated` - A callback that is called when the `queue.length()` hits the con
currency and further tasks will be queued. |
| 1277 * `empty` - A callback that is called when the last item from the `queue` is giv
en to a `worker`. |
| 1278 * `drain` - A callback that is called when the last item from the `queue` has re
turned from the `worker`. |
| 1279 * `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same met
hods and event calbacks as [`queue`](#queue) |
| 1280 |
| 1281 __Example__ |
| 1282 |
| 1283 ```js |
| 1284 // create a cargo object with payload 2 |
| 1285 |
| 1286 var cargo = async.cargo(function (tasks, callback) { |
| 1287 for(var i=0; i<tasks.length; i++){ |
| 1288 console.log('hello ' + tasks[i].name); |
| 1289 } |
| 1290 callback(); |
| 1291 }, 2); |
| 1292 |
| 1293 |
| 1294 // add some items |
| 1295 |
| 1296 cargo.push({name: 'foo'}, function (err) { |
| 1297 console.log('finished processing foo'); |
| 1298 }); |
| 1299 cargo.push({name: 'bar'}, function (err) { |
| 1300 console.log('finished processing bar'); |
| 1301 }); |
| 1302 cargo.push({name: 'baz'}, function (err) { |
| 1303 console.log('finished processing baz'); |
| 1304 }); |
| 1305 ``` |
| 1306 |
| 1307 --------------------------------------- |
| 1308 |
| 1309 <a name="auto" /> |
| 1310 ### auto(tasks, [concurrency], [callback]) |
| 1311 |
| 1312 Determines the best order for running the functions in `tasks`, based on their r
equirements. Each function can optionally depend on other functions being comple
ted first, and each function is run as soon as its requirements are satisfied. |
| 1313 |
| 1314 If any of the functions pass an error to their callback, the `auto` sequence wil
l stop. Further tasks will not execute (so any other functions depending on it w
ill not run), and the main `callback` is immediately called with the error. Fun
ctions also receive an object containing the results of functions which have com
pleted so far. |
| 1315 |
| 1316 Note, all functions are called with a `results` object as a second argument, |
| 1317 so it is unsafe to pass functions in the `tasks` object which cannot handle the |
| 1318 extra argument. |
| 1319 |
| 1320 For example, this snippet of code: |
| 1321 |
| 1322 ```js |
| 1323 async.auto({ |
| 1324 readData: async.apply(fs.readFile, 'data.txt', 'utf-8') |
| 1325 }, callback); |
| 1326 ``` |
| 1327 |
| 1328 will have the effect of calling `readFile` with the results object as the last |
| 1329 argument, which will fail: |
| 1330 |
| 1331 ```js |
| 1332 fs.readFile('data.txt', 'utf-8', cb, {}); |
| 1333 ``` |
| 1334 |
| 1335 Instead, wrap the call to `readFile` in a function which does not forward the |
| 1336 `results` object: |
| 1337 |
| 1338 ```js |
| 1339 async.auto({ |
| 1340 readData: function(cb, results){ |
| 1341 fs.readFile('data.txt', 'utf-8', cb); |
| 1342 } |
| 1343 }, callback); |
| 1344 ``` |
| 1345 |
| 1346 __Arguments__ |
| 1347 |
| 1348 * `tasks` - An object. Each of its properties is either a function or an array o
f |
| 1349 requirements, with the function itself the last item in the array. The object'
s key |
| 1350 of a property serves as the name of the task defined by that property, |
| 1351 i.e. can be used when specifying requirements for other tasks. |
| 1352 The function receives two arguments: (1) a `callback(err, result)` which must
be |
| 1353 called when finished, passing an `error` (which can be `null`) and the result
of |
| 1354 the function's execution, and (2) a `results` object, containing the results o
f |
| 1355 the previously executed functions. |
| 1356 * `concurrency` - An optional `integer` for determining the maximum number of ta
sks that can be run in parallel. By default, as many as possible. |
| 1357 * `callback(err, results)` - An optional callback which is called when all the |
| 1358 tasks have been completed. It receives the `err` argument if any `tasks` |
| 1359 pass an error to their callback. Results are always returned; however, if |
| 1360 an error occurs, no further `tasks` will be performed, and the results |
| 1361 object will only contain partial results. |
| 1362 |
| 1363 |
| 1364 __Example__ |
| 1365 |
| 1366 ```js |
| 1367 async.auto({ |
| 1368 get_data: function(callback){ |
| 1369 console.log('in get_data'); |
| 1370 // async code to get some data |
| 1371 callback(null, 'data', 'converted to array'); |
| 1372 }, |
| 1373 make_folder: function(callback){ |
| 1374 console.log('in make_folder'); |
| 1375 // async code to create a directory to store a file in |
| 1376 // this is run at the same time as getting the data |
| 1377 callback(null, 'folder'); |
| 1378 }, |
| 1379 write_file: ['get_data', 'make_folder', function(callback, results){ |
| 1380 console.log('in write_file', JSON.stringify(results)); |
| 1381 // once there is some data and the directory exists, |
| 1382 // write the data to a file in the directory |
| 1383 callback(null, 'filename'); |
| 1384 }], |
| 1385 email_link: ['write_file', function(callback, results){ |
| 1386 console.log('in email_link', JSON.stringify(results)); |
| 1387 // once the file is written let's email a link to it... |
| 1388 // results.write_file contains the filename returned by write_file. |
| 1389 callback(null, {'file':results.write_file, 'email':'user@example.com'}); |
| 1390 }] |
| 1391 }, function(err, results) { |
| 1392 console.log('err = ', err); |
| 1393 console.log('results = ', results); |
| 1394 }); |
| 1395 ``` |
| 1396 |
| 1397 This is a fairly trivial example, but to do this using the basic parallel and |
| 1398 series functions would look like this: |
| 1399 |
| 1400 ```js |
| 1401 async.parallel([ |
| 1402 function(callback){ |
| 1403 console.log('in get_data'); |
| 1404 // async code to get some data |
| 1405 callback(null, 'data', 'converted to array'); |
| 1406 }, |
| 1407 function(callback){ |
| 1408 console.log('in make_folder'); |
| 1409 // async code to create a directory to store a file in |
| 1410 // this is run at the same time as getting the data |
| 1411 callback(null, 'folder'); |
| 1412 } |
| 1413 ], |
| 1414 function(err, results){ |
| 1415 async.series([ |
| 1416 function(callback){ |
| 1417 console.log('in write_file', JSON.stringify(results)); |
| 1418 // once there is some data and the directory exists, |
| 1419 // write the data to a file in the directory |
| 1420 results.push('filename'); |
| 1421 callback(null); |
| 1422 }, |
| 1423 function(callback){ |
| 1424 console.log('in email_link', JSON.stringify(results)); |
| 1425 // once the file is written let's email a link to it... |
| 1426 callback(null, {'file':results.pop(), 'email':'user@example.com'}); |
| 1427 } |
| 1428 ]); |
| 1429 }); |
| 1430 ``` |
| 1431 |
| 1432 For a complicated series of `async` tasks, using the [`auto`](#auto) function ma
kes adding |
| 1433 new tasks much easier (and the code more readable). |
| 1434 |
| 1435 |
| 1436 --------------------------------------- |
| 1437 |
| 1438 <a name="retry" /> |
| 1439 ### retry([opts = {times: 5, interval: 0}| 5], task, [callback]) |
| 1440 |
| 1441 Attempts to get a successful response from `task` no more than `times` times bef
ore |
| 1442 returning an error. If the task is successful, the `callback` will be passed the
result |
| 1443 of the successful task. If all attempts fail, the callback will be passed the er
ror and |
| 1444 result (if any) of the final attempt. |
| 1445 |
| 1446 __Arguments__ |
| 1447 |
| 1448 * `opts` - Can be either an object with `times` and `interval` or a number. |
| 1449 * `times` - The number of attempts to make before giving up. The default is `
5`. |
| 1450 * `interval` - The time to wait between retries, in milliseconds. The default
is `0`. |
| 1451 * If `opts` is a number, the number specifies the number of times to retry, wi
th the default interval of `0`. |
| 1452 * `task(callback, results)` - A function which receives two arguments: (1) a `ca
llback(err, result)` |
| 1453 which must be called when finished, passing `err` (which can be `null`) and th
e `result` of |
| 1454 the function's execution, and (2) a `results` object, containing the results o
f |
| 1455 the previously executed functions (if nested inside another control flow). |
| 1456 * `callback(err, results)` - An optional callback which is called when the |
| 1457 task has succeeded, or after the final failed attempt. It receives the `err` a
nd `result` arguments of the last attempt at completing the `task`. |
| 1458 |
| 1459 The [`retry`](#retry) function can be used as a stand-alone control flow by pass
ing a callback, as shown below: |
| 1460 |
| 1461 ```js |
| 1462 // try calling apiMethod 3 times |
| 1463 async.retry(3, apiMethod, function(err, result) { |
| 1464 // do something with the result |
| 1465 }); |
| 1466 ``` |
| 1467 |
| 1468 ```js |
| 1469 // try calling apiMethod 3 times, waiting 200 ms between each retry |
| 1470 async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { |
| 1471 // do something with the result |
| 1472 }); |
| 1473 ``` |
| 1474 |
| 1475 ```js |
| 1476 // try calling apiMethod the default 5 times no delay between each retry |
| 1477 async.retry(apiMethod, function(err, result) { |
| 1478 // do something with the result |
| 1479 }); |
| 1480 ``` |
| 1481 |
| 1482 It can also be embedded within other control flow functions to retry individual
methods |
| 1483 that are not as reliable, like this: |
| 1484 |
| 1485 ```js |
| 1486 async.auto({ |
| 1487 users: api.getUsers.bind(api), |
| 1488 payments: async.retry(3, api.getPayments.bind(api)) |
| 1489 }, function(err, results) { |
| 1490 // do something with the results |
| 1491 }); |
| 1492 ``` |
| 1493 |
| 1494 |
| 1495 --------------------------------------- |
| 1496 |
| 1497 <a name="iterator" /> |
| 1498 ### iterator(tasks) |
| 1499 |
| 1500 Creates an iterator function which calls the next function in the `tasks` array, |
| 1501 returning a continuation to call the next one after that. It's also possible to |
| 1502 “peek” at the next iterator with `iterator.next()`. |
| 1503 |
| 1504 This function is used internally by the `async` module, but can be useful when |
| 1505 you want to manually control the flow of functions in series. |
| 1506 |
| 1507 __Arguments__ |
| 1508 |
| 1509 * `tasks` - An array of functions to run. |
| 1510 |
| 1511 __Example__ |
| 1512 |
| 1513 ```js |
| 1514 var iterator = async.iterator([ |
| 1515 function(){ sys.p('one'); }, |
| 1516 function(){ sys.p('two'); }, |
| 1517 function(){ sys.p('three'); } |
| 1518 ]); |
| 1519 |
| 1520 node> var iterator2 = iterator(); |
| 1521 'one' |
| 1522 node> var iterator3 = iterator2(); |
| 1523 'two' |
| 1524 node> iterator3(); |
| 1525 'three' |
| 1526 node> var nextfn = iterator2.next(); |
| 1527 node> nextfn(); |
| 1528 'three' |
| 1529 ``` |
| 1530 |
| 1531 --------------------------------------- |
| 1532 |
| 1533 <a name="apply" /> |
| 1534 ### apply(function, arguments..) |
| 1535 |
| 1536 Creates a continuation function with some arguments already applied. |
| 1537 |
| 1538 Useful as a shorthand when combined with other control flow functions. Any argum
ents |
| 1539 passed to the returned function are added to the arguments originally passed |
| 1540 to apply. |
| 1541 |
| 1542 __Arguments__ |
| 1543 |
| 1544 * `function` - The function you want to eventually apply all arguments to. |
| 1545 * `arguments...` - Any number of arguments to automatically apply when the |
| 1546 continuation is called. |
| 1547 |
| 1548 __Example__ |
| 1549 |
| 1550 ```js |
| 1551 // using apply |
| 1552 |
| 1553 async.parallel([ |
| 1554 async.apply(fs.writeFile, 'testfile1', 'test1'), |
| 1555 async.apply(fs.writeFile, 'testfile2', 'test2'), |
| 1556 ]); |
| 1557 |
| 1558 |
| 1559 // the same process without using apply |
| 1560 |
| 1561 async.parallel([ |
| 1562 function(callback){ |
| 1563 fs.writeFile('testfile1', 'test1', callback); |
| 1564 }, |
| 1565 function(callback){ |
| 1566 fs.writeFile('testfile2', 'test2', callback); |
| 1567 } |
| 1568 ]); |
| 1569 ``` |
| 1570 |
| 1571 It's possible to pass any number of additional arguments when calling the |
| 1572 continuation: |
| 1573 |
| 1574 ```js |
| 1575 node> var fn = async.apply(sys.puts, 'one'); |
| 1576 node> fn('two', 'three'); |
| 1577 one |
| 1578 two |
| 1579 three |
| 1580 ``` |
| 1581 |
| 1582 --------------------------------------- |
| 1583 |
| 1584 <a name="nextTick" /> |
| 1585 ### nextTick(callback), setImmediate(callback) |
| 1586 |
| 1587 Calls `callback` on a later loop around the event loop. In Node.js this just |
| 1588 calls `process.nextTick`; in the browser it falls back to `setImmediate(callback
)` |
| 1589 if available, otherwise `setTimeout(callback, 0)`, which means other higher prio
rity |
| 1590 events may precede the execution of `callback`. |
| 1591 |
| 1592 This is used internally for browser-compatibility purposes. |
| 1593 |
| 1594 __Arguments__ |
| 1595 |
| 1596 * `callback` - The function to call on a later loop around the event loop. |
| 1597 |
| 1598 __Example__ |
| 1599 |
| 1600 ```js |
| 1601 var call_order = []; |
| 1602 async.nextTick(function(){ |
| 1603 call_order.push('two'); |
| 1604 // call_order now equals ['one','two'] |
| 1605 }); |
| 1606 call_order.push('one') |
| 1607 ``` |
| 1608 |
| 1609 <a name="times" /> |
| 1610 ### times(n, iterator, [callback]) |
| 1611 |
| 1612 Calls the `iterator` function `n` times, and accumulates results in the same man
ner |
| 1613 you would use with [`map`](#map). |
| 1614 |
| 1615 __Arguments__ |
| 1616 |
| 1617 * `n` - The number of times to run the function. |
| 1618 * `iterator` - The function to call `n` times. |
| 1619 * `callback` - see [`map`](#map) |
| 1620 |
| 1621 __Example__ |
| 1622 |
| 1623 ```js |
| 1624 // Pretend this is some complicated async factory |
| 1625 var createUser = function(id, callback) { |
| 1626 callback(null, { |
| 1627 id: 'user' + id |
| 1628 }) |
| 1629 } |
| 1630 // generate 5 users |
| 1631 async.times(5, function(n, next){ |
| 1632 createUser(n, function(err, user) { |
| 1633 next(err, user) |
| 1634 }) |
| 1635 }, function(err, users) { |
| 1636 // we should now have 5 users |
| 1637 }); |
| 1638 ``` |
| 1639 |
| 1640 __Related__ |
| 1641 |
| 1642 * timesSeries(n, iterator, [callback]) |
| 1643 * timesLimit(n, limit, iterator, [callback]) |
| 1644 |
| 1645 |
| 1646 ## Utils |
| 1647 |
| 1648 <a name="memoize" /> |
| 1649 ### memoize(fn, [hasher]) |
| 1650 |
| 1651 Caches the results of an `async` function. When creating a hash to store functio
n |
| 1652 results against, the callback is omitted from the hash and an optional hash |
| 1653 function can be used. |
| 1654 |
| 1655 If no hash function is specified, the first argument is used as a hash key, whic
h may work reasonably if it is a string or a data type that converts to a distin
ct string. Note that objects and arrays will not behave reasonably. Neither will
cases where the other arguments are significant. In such cases, specify your ow
n hash function. |
| 1656 |
| 1657 The cache of results is exposed as the `memo` property of the function returned |
| 1658 by `memoize`. |
| 1659 |
| 1660 __Arguments__ |
| 1661 |
| 1662 * `fn` - The function to proxy and cache results from. |
| 1663 * `hasher` - An optional function for generating a custom hash for storing |
| 1664 results. It has all the arguments applied to it apart from the callback, and |
| 1665 must be synchronous. |
| 1666 |
| 1667 __Example__ |
| 1668 |
| 1669 ```js |
| 1670 var slow_fn = function (name, callback) { |
| 1671 // do something |
| 1672 callback(null, result); |
| 1673 }; |
| 1674 var fn = async.memoize(slow_fn); |
| 1675 |
| 1676 // fn can now be used as if it were slow_fn |
| 1677 fn('some name', function () { |
| 1678 // callback |
| 1679 }); |
| 1680 ``` |
| 1681 |
| 1682 <a name="unmemoize" /> |
| 1683 ### unmemoize(fn) |
| 1684 |
| 1685 Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoiz
ed |
| 1686 form. Handy for testing. |
| 1687 |
| 1688 __Arguments__ |
| 1689 |
| 1690 * `fn` - the memoized function |
| 1691 |
| 1692 --------------------------------------- |
| 1693 |
| 1694 <a name="ensureAsync" /> |
| 1695 ### ensureAsync(fn) |
| 1696 |
| 1697 Wrap an async function and ensure it calls its callback on a later tick of the e
vent loop. If the function already calls its callback on a next tick, no extra
deferral is added. This is useful for preventing stack overflows (`RangeError: M
aximum call stack size exceeded`) and generally keeping [Zalgo](http://blog.izs.
me/post/59142742143/designing-apis-for-asynchrony) contained. |
| 1698 |
| 1699 __Arguments__ |
| 1700 |
| 1701 * `fn` - an async function, one that expects a node-style callback as its last a
rgument |
| 1702 |
| 1703 Returns a wrapped function with the exact same call signature as the function pa
ssed in. |
| 1704 |
| 1705 __Example__ |
| 1706 |
| 1707 ```js |
| 1708 function sometimesAsync(arg, callback) { |
| 1709 if (cache[arg]) { |
| 1710 return callback(null, cache[arg]); // this would be synchronous!! |
| 1711 } else { |
| 1712 doSomeIO(arg, callback); // this IO would be asynchronous |
| 1713 } |
| 1714 } |
| 1715 |
| 1716 // this has a risk of stack overflows if many results are cached in a row |
| 1717 async.mapSeries(args, sometimesAsync, done); |
| 1718 |
| 1719 // this will defer sometimesAsync's callback if necessary, |
| 1720 // preventing stack overflows |
| 1721 async.mapSeries(args, async.ensureAsync(sometimesAsync), done); |
| 1722 |
| 1723 ``` |
| 1724 |
| 1725 --------------------------------------- |
| 1726 |
| 1727 <a name="constant"> |
| 1728 ### constant(values...) |
| 1729 |
| 1730 Returns a function that when called, calls-back with the values provided. Usefu
l as the first function in a `waterfall`, or for plugging values in to `auto`. |
| 1731 |
| 1732 __Example__ |
| 1733 |
| 1734 ```js |
| 1735 async.waterfall([ |
| 1736 async.constant(42), |
| 1737 function (value, next) { |
| 1738 // value === 42 |
| 1739 }, |
| 1740 //... |
| 1741 ], callback); |
| 1742 |
| 1743 async.waterfall([ |
| 1744 async.constant(filename, "utf8"), |
| 1745 fs.readFile, |
| 1746 function (fileData, next) { |
| 1747 //... |
| 1748 } |
| 1749 //... |
| 1750 ], callback); |
| 1751 |
| 1752 async.auto({ |
| 1753 hostname: async.constant("https://server.net/"), |
| 1754 port: findFreePort, |
| 1755 launchServer: ["hostname", "port", function (cb, options) { |
| 1756 startServer(options, cb); |
| 1757 }], |
| 1758 //... |
| 1759 }, callback); |
| 1760 |
| 1761 ``` |
| 1762 |
| 1763 --------------------------------------- |
| 1764 |
| 1765 <a name="asyncify"> |
| 1766 <a name="wrapSync"> |
| 1767 ### asyncify(func) |
| 1768 |
| 1769 __Alias:__ `wrapSync` |
| 1770 |
| 1771 Take a sync function and make it async, passing its return value to a callback.
This is useful for plugging sync functions into a waterfall, series, or other as
ync functions. Any arguments passed to the generated function will be passed to
the wrapped function (except for the final callback argument). Errors thrown wil
l be passed to the callback. |
| 1772 |
| 1773 __Example__ |
| 1774 |
| 1775 ```js |
| 1776 async.waterfall([ |
| 1777 async.apply(fs.readFile, filename, "utf8"), |
| 1778 async.asyncify(JSON.parse), |
| 1779 function (data, next) { |
| 1780 // data is the result of parsing the text. |
| 1781 // If there was a parsing error, it would have been caught. |
| 1782 } |
| 1783 ], callback) |
| 1784 ``` |
| 1785 |
| 1786 If the function passed to `asyncify` returns a Promise, that promises's resolved
/rejected state will be used to call the callback, rather than simply the synchr
onous return value. Example: |
| 1787 |
| 1788 ```js |
| 1789 async.waterfall([ |
| 1790 async.apply(fs.readFile, filename, "utf8"), |
| 1791 async.asyncify(function (contents) { |
| 1792 return db.model.create(contents); |
| 1793 }), |
| 1794 function (model, next) { |
| 1795 // `model` is the instantiated model object. |
| 1796 // If there was an error, this function would be skipped. |
| 1797 } |
| 1798 ], callback) |
| 1799 ``` |
| 1800 |
| 1801 This also means you can asyncify ES2016 `async` functions. |
| 1802 |
| 1803 ```js |
| 1804 var q = async.queue(async.asyncify(async function (file) { |
| 1805 var intermediateStep = await processFile(file); |
| 1806 return await somePromise(intermediateStep) |
| 1807 })); |
| 1808 |
| 1809 q.push(files); |
| 1810 ``` |
| 1811 |
| 1812 --------------------------------------- |
| 1813 |
| 1814 <a name="log" /> |
| 1815 ### log(function, arguments) |
| 1816 |
| 1817 Logs the result of an `async` function to the `console`. Only works in Node.js o
r |
| 1818 in browsers that support `console.log` and `console.error` (such as FF and Chrom
e). |
| 1819 If multiple arguments are returned from the async function, `console.log` is |
| 1820 called on each argument in order. |
| 1821 |
| 1822 __Arguments__ |
| 1823 |
| 1824 * `function` - The function you want to eventually apply all arguments to. |
| 1825 * `arguments...` - Any number of arguments to apply to the function. |
| 1826 |
| 1827 __Example__ |
| 1828 |
| 1829 ```js |
| 1830 var hello = function(name, callback){ |
| 1831 setTimeout(function(){ |
| 1832 callback(null, 'hello ' + name); |
| 1833 }, 1000); |
| 1834 }; |
| 1835 ``` |
| 1836 ```js |
| 1837 node> async.log(hello, 'world'); |
| 1838 'hello world' |
| 1839 ``` |
| 1840 |
| 1841 --------------------------------------- |
| 1842 |
| 1843 <a name="dir" /> |
| 1844 ### dir(function, arguments) |
| 1845 |
| 1846 Logs the result of an `async` function to the `console` using `console.dir` to |
| 1847 display the properties of the resulting object. Only works in Node.js or |
| 1848 in browsers that support `console.dir` and `console.error` (such as FF and Chrom
e). |
| 1849 If multiple arguments are returned from the async function, `console.dir` is |
| 1850 called on each argument in order. |
| 1851 |
| 1852 __Arguments__ |
| 1853 |
| 1854 * `function` - The function you want to eventually apply all arguments to. |
| 1855 * `arguments...` - Any number of arguments to apply to the function. |
| 1856 |
| 1857 __Example__ |
| 1858 |
| 1859 ```js |
| 1860 var hello = function(name, callback){ |
| 1861 setTimeout(function(){ |
| 1862 callback(null, {hello: name}); |
| 1863 }, 1000); |
| 1864 }; |
| 1865 ``` |
| 1866 ```js |
| 1867 node> async.dir(hello, 'world'); |
| 1868 {hello: 'world'} |
| 1869 ``` |
| 1870 |
| 1871 --------------------------------------- |
| 1872 |
| 1873 <a name="noConflict" /> |
| 1874 ### noConflict() |
| 1875 |
| 1876 Changes the value of `async` back to its original value, returning a reference t
o the |
| 1877 `async` object. |
| OLD | NEW |