How to make array.forEach(asyncfn) synchronized?

后端 未结 4 1991
渐次进展
渐次进展 2021-01-27 06:17

Say I have an array and I want to perform an async-function on each element of the array.

let a = [x1, x2, x3]

// I want to
await a.forEach(async (x) => {...         


        
相关标签:
4条回答
  • 2021-01-27 06:43

    I've been using this function for a while, in case if a dedicated library is not desired:

    // usage: 
    
    // array.asyncEach(function(item, resume) {
    //   do something...
    //   console.log(item); 
    //   resume(); // call `resume()` to resume the cycle
    // }
    //
    // unless resume() is called, loop doesn't proceed to the next item
    
    Array.prototype.asyncEach = function(iterator) {
      var list    = this,
          n       = list.length,
          i       = -1,
          calls   = 0,
          looping = false;
    
      var iterate = function() {
        calls -= 1;
        i += 1;
        if (i === n) return;
        iterator(list[i], resume);
      };
    
      var loop = function() {
        if (looping) return;
        looping = true;
        while (calls > 0) iterate();
        looping = false;
      };
    
      var resume = function() {
        calls += 1;
        if (typeof setTimeout === 'undefined') loop();
        else setTimeout(iterate, 1);
      };
      resume();
    };

    Perform any async tasks inside the function, and call resume() when you are done.

    I don't remember where did I get this function from.

    0 讨论(0)
  • 2021-01-27 06:56

    I have used a library called async. There a function called eachSeries. It takes an array, an async function, and a callback. The function is called on each item for the array.

    This question can open a rabbit hole of complexity. You will need to be careful that your async function doesn't make an asynchronous call. The library provides a callback that can be useful in this case.

    function asyncFunction(val, callback) {
    
       return (function() {
         //do stuff
    
         callback();
       })();
    }
    

    The callback will initiate the a call on the next item in the array.

    0 讨论(0)
  • 2021-01-27 07:01
    Is there any specific event on which these function will be called ?
    if yes can be achieved through **closure** in javascript.
    

    right now your function will be called with last value in array when you invoke it

    0 讨论(0)
  • 2021-01-27 07:04

    Like this?

    for (let x of a) {
      await fn(x);
    }
    

    Or if you really dislike creating a separate fn:

    for (let x of a) {
      await (async v => {
        ...
      })(x);
    }
    

    You could even add it to Array.prototype:

    Array.prototype.resolveSeries = async function(fn) {
      for (let x of this) {
        await fn(x);
      }
    }
    
    // Usage:
    await a.resolveSeries(fn);
    
    // Or:
    await a.resolveSeries(async x => {
      ...
    });
    
    0 讨论(0)
提交回复
热议问题