如何使array.forEach(asyncfn)同步?

时间:2017-05-13 09:58:34

标签: javascript

假设我有一个数组,我想对数组的每个元素执行异步函数。

let a = [x1, x2, x3]

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

// which equals to
let fn = async (x) => {...}
await fn(x1)
await fn(x2)
await fn(x3)

我该怎么做?

4 个答案:

答案 0 :(得分:3)

喜欢这个吗?

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

或者,如果您真的不喜欢创建单独的fn

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

您甚至可以将其添加到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 => {
  ...
});

答案 1 :(得分:0)

Is there any specific event on which these function will be called ?
if yes can be achieved through **closure** in javascript.

现在,当您调用函数时,将使用数组中的最后一个值调用函数

答案 2 :(得分:0)

我使用了一个名为http://my.domain.com/videos/289522.mp4的库。有一个名为eachSeries的函数。它需要一个数组,一个异步函数和一个回调。在数组的每个项目上调用该函数。

这个问题可以打开一个复杂的兔子洞。您需要注意异步函数不会进行异步调用。该库提供了一个在这种情况下很有用的回调。

function asyncFunction(val, callback) {

   return (function() {
     //do stuff

     callback();
   })();
}

回调将启动对数组中下一项的调用。

答案 3 :(得分:0)

如果不需要专用库,我已经使用了这个功能一段时间了:



// 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();
};




在函数内执行任何异步任务,并在完成后调用resume()

我不记得从哪里获得此功能。