Callback after all asynchronous forEach callbacks are completed

后端 未结 13 2049
谎友^
谎友^ 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:07

    My solution without Promise (this ensures that every action is ended before the next one begins):

    Array.prototype.forEachAsync = function (callback, end) {
            var self = this;
        
            function task(index) {
                var x = self[index];
                if (index >= self.length) {
                    end()
                }
                else {
                    callback(self[index], index, self, function () {
                        task(index + 1);
                    });
                }
            }
        
            task(0);
        };
        
        
        var i = 0;
        var myArray = Array.apply(null, Array(10)).map(function(item) { return i++; });
        console.log(JSON.stringify(myArray));
        myArray.forEachAsync(function(item, index, arr, next){
          setTimeout(function(){
            $(".toto").append("<div>item index " + item + " done</div>");
            console.log("action " + item + " done");
            next();
          }, 300);
        }, function(){
            $(".toto").append("<div>ALL ACTIONS ARE DONE</div>");
            console.log("ALL ACTIONS ARE DONE");
        });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="toto">
    
    </div>

    0 讨论(0)
  • 2020-11-22 13:09
    var i=0;
    const waitFor = (ms) => 
    { 
      new Promise((r) => 
      {
       setTimeout(function () {
       console.log('timeout completed: ',ms,' : ',i); 
         i++;
         if(i==data.length){
          console.log('Done')  
        }
      }, ms); 
     })
    }
    var data=[1000, 200, 500];
    data.forEach((num) => {
      waitFor(num)
    })
    
    0 讨论(0)
  • 2020-11-22 13:11

    This is the solution for Node.js which is asynchronous.

    using the async npm package.

    (JavaScript) Synchronizing forEach Loop with callbacks inside

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

    I try Easy Way to resolve it, share it with you :

    let counter = 0;
                arr.forEach(async (item, index) => {
                    await request.query(item, (err, recordset) => {
                        if (err) console.log(err);
    
                        //do Somthings
    
                        counter++;
                        if(counter == tableCmd.length){
                            sql.close();
                            callback();
                        }
                    });
    

    request is Function of mssql Library in Node js. This can replace each function or Code u want. GoodLuck

    0 讨论(0)
  • 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);
    });
    
    0 讨论(0)
  • 2020-11-22 13:17
     var counter = 0;
     var listArray = [0, 1, 2, 3, 4];
     function callBack() {
         if (listArray.length === counter) {
             console.log('All Done')
         }
     };
     listArray.forEach(function(element){
         console.log(element);
         counter = counter + 1;
         callBack();
     });
    
    0 讨论(0)
提交回复
热议问题