Callback after all asynchronous forEach callbacks are completed

后端 未结 13 2227
谎友^
谎友^ 2020-11-22 12:56

As the title suggests. How do I do this?

I want to call whenAllDone() after the forEach-loop has gone through each element and done some asynchronous p

13条回答
  •  孤独总比滥情好
    2020-11-22 13:17

    It's odd how many incorrect answers has been given to asynchronous case! It can be simply shown that checking index does not provide expected behavior:

    // INCORRECT
    var list = [4000, 2000];
    list.forEach(function(l, index) {
        console.log(l + ' started ...');
        setTimeout(function() {
            console.log(index + ': ' + l);
        }, l);
    });
    

    output:

    4000 started
    2000 started
    1: 2000
    0: 4000
    

    If we check for index === array.length - 1, callback will be called upon completion of first iteration, whilst first element is still pending!

    To solve this problem without using external libraries such as async, I think your best bet is to save length of list and decrement if after each iteration. Since there's just one thread we're sure there no chance of race condition.

    var list = [4000, 2000];
    var counter = list.length;
    list.forEach(function(l, index) {
        console.log(l + ' started ...');
        setTimeout(function() {
            console.log(index + ': ' + l);
            counter -= 1;
            if ( counter === 0)
                // call your callback here
        }, l);
    });
    

提交回复
热议问题