JavaScript, Node.js: is Array.forEach asynchronous?

后端 未结 10 1455
时光说笑
时光说笑 2020-11-22 10:47

I have a question regarding the native Array.forEach implementation of JavaScript: Does it behave asynchronously? For example, if I call:

[many          


        
相关标签:
10条回答
  • 2020-11-22 11:53

    This is a short asynchronous function to use without requiring third party libs

    Array.prototype.each = function (iterator, callback) {
        var iterate = function () {
                pointer++;
                if (pointer >= this.length) {
                    callback();
                    return;
                }
                iterator.call(iterator, this[pointer], iterate, pointer);
        }.bind(this),
            pointer = -1;
        iterate(this);
    };
    
    0 讨论(0)
  • 2020-11-22 11:53

    It is possible to code even the solution like this for example :

     var loop = function(i, data, callback) {
        if (i < data.length) {
            //TODO("SELECT * FROM stackoverflowUsers;", function(res) {
                //data[i].meta = res;
                console.log(i, data[i].title);
                return loop(i+1, data, errors, callback);
            //});
        } else {
           return callback(data);
        }
    };
    
    loop(0, [{"title": "hello"}, {"title": "world"}], function(data) {
        console.log("DONE\n"+data);
    });
    

    On the other hand, it is much slower than a "for".

    Otherwise, the excellent Async library can do this: https://caolan.github.io/async/docs.html#each

    0 讨论(0)
  • 2020-11-22 11:53

    Here is a small example you can run to test it:

    [1,2,3,4,5,6,7,8,9].forEach(function(n){
        var sum = 0;
        console.log('Start for:' + n);
        for (var i = 0; i < ( 10 - n) * 100000000; i++)
            sum++;
    
        console.log('Ended for:' + n, sum);
    });
    

    It will produce something like this(if it takes too less/much time, increase/decrease the number of iterations):

    (index):48 Start for:1
    (index):52 Ended for:1 900000000
    (index):48 Start for:2
    (index):52 Ended for:2 800000000
    (index):48 Start for:3
    (index):52 Ended for:3 700000000
    (index):48 Start for:4
    (index):52 Ended for:4 600000000
    (index):48 Start for:5
    (index):52 Ended for:5 500000000
    (index):48 Start for:6
    (index):52 Ended for:6 400000000
    (index):48 Start for:7
    (index):52 Ended for:7 300000000
    (index):48 Start for:8
    (index):52 Ended for:8 200000000
    (index):48 Start for:9
    (index):52 Ended for:9 100000000
    (index):45 [Violation] 'load' handler took 7285ms
    
    0 讨论(0)
  • 2020-11-22 11:53

    Use Promise.each of bluebird library.

    Promise.each(
    Iterable<any>|Promise<Iterable<any>> input,
    function(any item, int index, int length) iterator
    ) -> Promise
    

    This method iterates over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given iterator function with the signature (value, index, length) where the value is the resolved value of a respective promise in the input array. Iteration happens serially. If the iterator function returns a promise or a thenable, then the result of the promise is awaited before continuing with next iteration. If any promise in the input array is rejected, then the returned promise is rejected as well.

    If all of the iterations resolve successfully, Promise.each resolves to the original array unmodified. However, if one iteration rejects or errors, Promise.each ceases execution immediately and does not process any further iterations. The error or rejected value is returned in this case instead of the original array.

    This method is meant to be used for side effects.

    var fileNames = ["1.txt", "2.txt", "3.txt"];
    
    Promise.each(fileNames, function(fileName) {
        return fs.readFileAsync(fileName).then(function(val){
            // do stuff with 'val' here.  
        });
    }).then(function() {
    console.log("done");
    });
    
    0 讨论(0)
提交回复
热议问题