我会这样做
就个人而言,我不是 Promise 的忠实粉丝。我认为 API 非常冗长,生成的代码很难阅读。下面定义的方法会生成非常扁平的代码,并且更容易立即理解发生了什么。至少在我看来。
这是我为回复this question而创建的一个小东西
// void asyncForEach(Array arr, Function iterator, Function callback)
// * iterator(item, done) - done can be called with an err to shortcut to callback
// * callback(done) - done recieves error if an iterator sent one
function asyncForEach(arr, iterator, callback) {
// create a cloned queue of arr
var queue = arr.slice(0);
// create a recursive iterator
function next(err) {
// if there's an error, bubble to callback
if (err) return callback(err);
// if the queue is empty, call the callback with no error
if (queue.length === 0) return callback(null);
// call the callback with our task
// we pass `next` here so the task can let us know when to move on to the next task
iterator(queue.shift(), next);
}
// start the loop;
next();
}
你可以这样使用
var urls = [
"http://example.com/cat",
"http://example.com/hat",
"http://example.com/wat"
];
function eachUrl(url, done){
http.get(url, function(res) {
// do something with res
done();
}).on("error", function(err) {
done(err);
});
}
function urlsDone(err) {
if (err) throw err;
console.log("done getting all urls");
}
asyncForEach(urls, eachUrl, urlsDone);
这样做的好处
- 没有外部依赖或 beta api
- 可在您想要执行异步任务的任何阵列上重复使用
- 非阻塞,正如您对 node 所期望的那样
- 可以轻松适应并行处理
- 通过编写自己的实用程序,您可以更好地了解这种事情的工作原理
如果您只想获取一个模块来帮助您,请查看 async 和 async.eachSeries 方法。