2017-05-13 31 views
0

说我有一个数组,我想对数组的每个元素执行一个异步函数。如何使array.forEach(asyncfn)同步?

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) 

我该怎么做?

回答

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

,现在你的函数将与数组最后的值被调用,当你调用它

0

我使用了一个叫做async库。有一个叫做eachSeries的功能。它需要一个数组,一个异步函数和一个回调函数。该函数在数组的每个项目上被调用。

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

function asyncFunction(val, callback) { 

    return (function() { 
    //do stuff 

    callback(); 
    })(); 
} 

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

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

是否有可能使这个功能更强大? – bitweaver

+0

@bitweaver请参阅编辑。它基本上是相同的代码,但封装在自定义数组方法中。 – robertklep

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()当您完成。

我不记得我从哪里得到这个功能。

+0

hmm;一个forEach调用值和索引(和self);为什么不是迭代器(list [i],i,resume)? – frumbert