嗨,我正在尝试使用下划线 js 创建一个同步循环。对于每个循环迭代,我都会进行一些进一步的异步调用。但是,我需要等到每次迭代调用完成后才能继续下一次迭代。
这在下划线js中可能吗?如果是,怎么会这样?有人可以提供一个例子吗?
_.( items ).each( function(item) {
// make aync call and wait till done
processItem(item, function callBack(data, err){
// success. ready to move to the next item.
});
// need to wait till processItem is done.
});
更新 我使用 async.eachSeries 方法解决了这个问题。
async.eachSeries( items, function( item, callback){
processItem(item, function callBack(data, err){
// Do the processing....
// success. ready to move to the next item.
callback(); // the callback is used to flag success
// andgo back to the next iteration
});
});
最佳答案
您不能使用同步循环结构,例如下划线的.each()
,因为它不会等待异步操作完成后再进入下一次迭代,而且它不能在像 Javascript 这样的单线程世界中这样做。
您必须使用专门支持异步操作的循环构造。有很多可供选择 - 您可以轻松构建自己的库,或者使用 Node.js 中的异步库,或者让 Promise 为您排序。这是一篇关于下划线异步控制的文章:daemon.co.za/2012/04/simple-async-with-only-underscore。
这是我使用的一种常见设计模式:
function processData(items) {
// works when items is an array-like data structure
var index = 0;
function next() {
if (index < items.length) {
// note, I switched the order of the arguments to your callback to be more "node-like"
processItem(items[index], function(err, data) {
// error handling goes here
++index;
next();
}
}
}
// start the first iteration
next();
}
<小时/>
对于 Node.js 的预构建库,async library经常用于此目的。它具有许多用于迭代集合的流行方法的异步版本,例如 .map()
、.each()
、.reduce()
等...就您而言,我认为您会寻找 .eachSeries()
强制异步操作一个接一个地运行(而不是并行)。
对于使用 promise ,Bluebird promise library有一个具有异步功能的 .each()
,它在解决 Promise 时调用下一个迭代,允许您在迭代器中使用异步操作,但保持顺序执行。
关于node.js - 如何在underscore js中结合使用after和each来创建同步循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25918213/