Blame view

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