Initial commit
[yaffs-website] / node_modules / async-foreach / dist / ba-foreach.js
1 /* JavaScript Sync/Async forEach - v0.1.2 - 1/10/2012
2  * http://github.com/cowboy/javascript-sync-async-foreach
3  * Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */
4
5 (function(exports) {
6
7   // Iterate synchronously or asynchronously.
8   exports.forEach = function(arr, eachFn, doneFn) {
9     var i = -1;
10     // Resolve array length to a valid (ToUint32) number.
11     var len = arr.length >>> 0;
12
13     // This IIFE is called once now, and then again, by name, for each loop
14     // iteration.
15     (function next(result) {
16       // This flag will be set to true if `this.async` is called inside the
17       // eachFn` callback.
18       var async;
19       // Was false returned from the `eachFn` callback or passed to the
20       // `this.async` done function?
21       var abort = result === false;
22
23       // Increment counter variable and skip any indices that don't exist. This
24       // allows sparse arrays to be iterated.
25       do { ++i; } while (!(i in arr) && i !== len);
26
27       // Exit if result passed to `this.async` done function or returned from
28       // the `eachFn` callback was false, or when done iterating.
29       if (abort || i === len) {
30         // If a `doneFn` callback was specified, invoke that now. Pass in a
31         // boolean value representing "not aborted" state along with the array.
32         if (doneFn) {
33           doneFn(!abort, arr);
34         }
35         return;
36       }
37
38       // Invoke the `eachFn` callback, setting `this` inside the callback to a
39       // custom object that contains one method, and passing in the array item,
40       // index, and the array.
41       result = eachFn.call({
42         // If `this.async` is called inside the `eachFn` callback, set the async
43         // flag and return a function that can be used to continue iterating.
44         async: function() {
45           async = true;
46           return next;
47         }
48       }, arr[i], i, arr);
49
50       // If the async flag wasn't set, continue by calling `next` synchronously,
51       // passing in the result of the `eachFn` callback.
52       if (!async) {
53         next(result);
54       }
55     }());
56   };
57
58 }(typeof exports === "object" && exports || this));