async.waterfall
嵌套在async.forEachOfLimit
循环中,如下面的代码所示。
问题:当代码在async.waterfall
内执行步骤时,如何跳过async.forEachLimit
的迭代?换句话说,脱离async.waterfall
回到async.forEachLimit
。我在代码中注释了应该进行此检查的位置
当前代码给出错误Callback was already called.
同样,当我想打破async.waterfall
时,如果我使用return callback()
代替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()
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
在您的第一个解决方案中,当索引匹配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')
})
在第二种解决方案中,如果index匹配1,则不带参数调用callback,并跳过带空参数调用callback。还是没有冲出瀑布
用瀑布法解决你的问题,你有两个选择。
用一个error参数调用waterfall的callback方法,它会跳出waterfall,然后在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) 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') });
在每个瀑布式方法的开头跳过其余的代码并立即调用回调(这是你在第二次尝试中所做的)
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') })