我正在编写async.parallel的幼稚实施作为学习练习。以下是文档中的说明:
parallel(tasks,[callback])运行tasks中的tasks数组 并行,无需等到上一个功能完成。 如果任何函数将错误传递给其回调,则为main 立即使用错误值调用回调。一旦 任务完成后,结果将传递给最终的回调函数 一个数组。
我不确定如何提前退出,如果其中一个函数返回错误。我传递回调是一个错误,但当然其他功能继续执行。
以下是我到目前为止的情况;随时可以在您的机器上试用。
function parallel(tasks, cb) {
cb = cb || function() {};
if (!Array.isArray(tasks)) return cb('tasks must be an array');
if (!tasks.length) return cb();
var res = [];
var completed_count = 0;
for (var i=0; i<tasks.length; i++) {
(function(ind) {
tasks[ind](function(err, val) {
if (err) return complete(err); // <--- !
res[ind] = val;
completed_count++;
if (completed_count === tasks.length) complete(null, res);
});
} (i));
}
};
// ===== test functions =====
function slow(time, cb) {
setTimeout(function() {
cb(null, time);
}, time);
};
function slowError(time, cb) {
setTimeout(function() {
cb('Some Error', time);
}, time);
}
function complete(err, results) {
if (err) return console.log(err);
else return console.log(results);
};
// ===== tests =====
// should return [1000, 2000, 3000]
parallel([slow.bind(null, 1000),
slow.bind(null, 2000),
slow.bind(null, 3000)], complete);
// should exit early
parallel([slowError.bind(null, 1000),
slowError.bind(null, 2000),
slow.bind(null, 3000)], complete);
答案 0 :(得分:1)
你必须在parallel
函数中存储整个执行的状态,并在每次回调时检查这个:应该是错误/完成状态的状态,每个下一个回调都应该被解除。像这样:
function parallel(tasks, cb) {
var result = [];
var await = tasks.length;
tasks.forEach(function(task, i){
task(function(err, val){
if (await === 0) return;
if (err) {
await = 0;
cb(err);
return;
}
result[i] = val;
if (--await === 0) cb(null, result);
})
});
}
我在这里使用倒计时来匹配结束或完成状态。例如,您也可以使用errored
布尔标志,或者您想要保存状态的任何内容,并在每次回调时检查它。
答案 1 :(得分:1)
但当然其他功能继续执行
是。你不能做任何事情,因为他们没有为你提供取消它们的方法。 async.js
也没有做任何事情,你只需要让它们运行。
我不确定如何退出
但“让他们跑”并不意味着你必须等待他们。您可以立即触发回调 - 这是他们正在谈论的“直接”退出。
你的实施中的一些要点你没有做得对:
callback
。如果您没有这样做,用户希望您和他们的应用程序会疯狂。我会把这些作为练习留给你: - )