我想在发生第一个任务错误后停止执行我的async.queue。我需要与并发限制并行执行几个类似的操作,但在第一次出错后停止所有操作。我怎么能这样做或者我应该用什么呢?
答案 0 :(得分:6)
假设你发射了5个并行函数,每个函数需要5秒钟。在第3秒,功能1失败。那你怎么能停止其余部分的执行呢?
这取决于这些函数的作用,您可以使用setInterval进行轮询。但是,如果您的问题是如何阻止将其他任务推送到队列中。你可以这样做:
q.push(tasks, function (err) {
if (err && !called) {
//Will prevent async to push more tasks to the queue, however please note that
//whatever pushed to the queue, it will be processed anyway.
q.kill();
//This will not allow double calling for the final callback
called = true;
//This the main process callback, the final callback
main(err, results);
}
});
这是一个完整的工作示例:
var async = require('async');
/*
This function is the actual work you are trying to do.
Please note for example if you are running child processes
here, by doing q.kill you will not stop the execution
of those processes, so you need actually to keep track the
spawned processed and then kill them when you call q.kill
in 'pushCb' function. In-case of just long running function,
you may poll using setInterval
*/
function worker(task, wcb) {
setTimeout(function workerTimeout() {
if (task === 11 || task === 12 || task === 3) {
return wcb('error in processing ' + task);
}
wcb(null, task + ' got processed');
}, Math.floor(Math.random() * 100));
}
/*
This function that will push the tasks to async.queue,
and then hand them to your worker function
*/
function process(tasks, concurrency, pcb) {
var results = [], called = false;
var q = async.queue(function qWorker(task, qcb) {
worker(task, function wcb(err, data) {
if (err) {
return qcb(err); //Here how we propagate error to qcb
}
results.push(data);
qcb();
});
}, concurrency);
/*
The trick is in this function, note that checking q.tasks.length
does not work q.kill introduced in async 0.7.0, it is just setting
the drain function to null and the tasks length to zero
*/
q.push(tasks, function qcb(err) {
if (err && !called) {
q.kill();
called = true;
pcb(err, results);
}
});
q.drain = function drainCb() {
pcb(null, results);
}
}
var tasks = [];
var concurrency = 10;
for (var i = 1; i <= 20; i += 1) {
tasks.push(i);
}
process(tasks, concurrency, function pcb(err, results) {
console.log(results);
if (err) {
return console.log(err);
}
console.log('done');
});
答案 1 :(得分:2)
github页面上的异步文档是过时的还是不正确的,同时检查async.queue()方法返回的队列对象我没有看到方法kill()。
然而,有一种解决方法。队列对象有属性任务,这是一个数组,只需为空数组分配一个引用就可以了。对此我不知道。
queue.push( someTasks, function ( err ) {
if ( err ) queue.tasks = [];
});