Skip to content Skip to sidebar Skip to footer

How To Make Array.forEach(asyncfn) Synchronized?

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) => {...}) // which equals

Solution 1:

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 => {
  ...
});

Solution 2:

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.


Solution 3:

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.


Solution 4:

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


Post a Comment for "How To Make Array.forEach(asyncfn) Synchronized?"