async.waterfall
嵌套在async.forEachOfLimit
循环中,如下面的代码所示。
问题:当代码执行async.forEachLimit
内的步骤时,如何跳过async.waterfall
的迭代?换句话说,突破async.waterfall
并返回async.forEachLimit
。我已经在代码中评论了应该进行此项检查的位置
当前代码提供错误Callback was already called.
此外,如果我想要突破return callback()
时使用cb()
代替async.waterfall
,则不会发生错误,但不会跳过此错误。
var async = require('async')
var users = ['a','b','c']
async.forEachOfLimit(users, 1, function(user, index, cb) {
console.log(index + ': ' + user)
async.waterfall([
function(callback) {
callback(null);
},
function(callback) {
// Skip async.forEAchOfLimit iteration when index == 1
if(index == 1)
cb()
callback(null);
}
], function (err, result) {
console.log(index + ": done")
cb()
});
}, function() {
console.log('ALL done')
})
错误
0: a
0: done
1: b
2: c
1: done
/Users/x/test/node_modules/async/lib/async.js:43
if (fn === null) throw new Error("Callback was already called.");
^
Error: Callback was already called.
所需输出
0: a
0: done
1: b
2: c
2: done
ALL done
使用return callback()
var async = require('async')
var users = ['a','b','c']
async.forEachOfLimit(users, 1, function(user, index, cb) {
console.log(index + ': ' + user)
async.waterfall([
function(callback) {
callback(null);
},
function(callback) {
// Skip async.forEAchOfLimit iteration when index == 1
if(index == 1)
return callback()
callback(null);
}
], function (err, result) {
console.log(index + ": done")
cb()
});
}, function() {
console.log('ALL done')
})
输出
没有爆发......
0: a
0: done
1: b
1: done
2: c
2: done
ALL done
答案 0 :(得分:2)
在索引匹配1的第一个解决方案中,cb
被调用两次,这就是导致Callback was already called
错误的原因。虽然您调用forEachOfLimit回调cb
,但您的代码不会停止执行并调用回调。在回调函数cb
中再次执行。
var async = require('async')
var users = ['a','b','c']
async.forEachOfLimit(users, 1, function(user, index, cb) {
console.log(index + ': ' + user)
async.waterfall([
function(callback) {
callback(null);
},
function(callback) {
// Skip async.forEAchOfLimit iteration when index == 1
if(index == 1)
cb() // First callback call
callback(null);
}
], function (err, result) {
console.log(index + ": done")
cb() // Second callback call
});
}, function() {
console.log('ALL done')
})
在第二个解决方案中,如果索引匹配1,则它调用不带参数的回调,并跳过使用null参数调用回调。仍然没有突破瀑布。
要使用瀑布解决您的问题,您有两种选择。
使用error参数调用瀑布的方法回调,该参数突破了瀑布而不是在瀑布的回调中处理此错误。
var async = require('async')
var users = ['a','b','c']
async.forEachOfLimit(users, 1, function(user, index, cb) {
console.log(index + ': ' + user)
async.waterfall([
function(callback) {
callback(null);
},
function(callback) {
// Skip async.forEAchOfLimit iteration when index == 1
if(index == 1)
return callback(new Error('Index equals 1'));
callback(null);
}
], function (err, result) {
console.log(index + ": done")
if(err.message == 'Index equals 1') {
err = null; // If you want to continue executing forEachOfLimit no error must be passed to cb
}
cb(err, result);
});
}, function() {
console.log('ALL done')
});
在每个waterfalled方法的开头跳过剩下的代码并立即调用回调(这是你在第二次尝试时所做的)
var async = require('async')
var users = ['a','b','c']
async.forEachOfLimit(users, 1, function(user, index, cb) {
console.log(index + ': ' + user)
async.waterfall([
function(callback) {
callback(null);
},
function(callback) {
// Skip execution of the rest of waterfall method immediately
if(index == 1)
return callback()
// Some additional code here
callback(null);
}
], function (err, result) {
console.log(index + ": done")
cb()
});
}, function() {
console.log('ALL done')
})