我试图执行两个函数异步系列与node.JS。但是我不明白为什么要这样做。
现在,我有:
功能1:
function search(client_id, callback) {
clientRedis.keys('director:*', function (err, results) {
results.forEach(function (key) {
clientRedis.hgetall(key, function (err, obj) {
//SAVE RESULT
console.log('save');
});
});
});
callback(null, results);
}
功能2:
function range(client_id, callback) {
//Sort my array
callback(null, results);
}
我在这里调用函数:
async.series([
search(client_id),
range(client_id);
], function (err, result) {
console.log(err);
console.log(result);
});
我的问题:第二个函数在第一个函数之前执行,因为第一个函数花费更多的时间。
如果你不打算在第二个函数中直接使用第一个函数的结果(仅通过redis),你可以使用这样的东西:
async.series([
search.bind(null, client_id),
range.bind(null, client_id)
], function (err, results) {
console.log(err);
console.log(results[0]); // for search results
console.log(results[1]); // for range results
});
search(client_id)
和range(client_id)
将立即执行,将callback
参数分配给undefined
,然后async.series
将尝试执行这些函数的结果作为一个系列,并且可能失败,因为这些不是函数,而是undefined
。或者更确切地说,如果函数不尝试执行undefined(null, results)
.
请记住,如果f
是一个函数,f(...)
执行它。你需要将函数本身传递给async.series
,而不是它们的执行结果。
async.series
希望你传入一个任务数组或对象,每个任务都是function(callback) { ... }
。
因此,下面的代码应该有帮助:
async.series([
function(callback) { search(client_id, callback); },
function(callback) { range(client_id, callback); }
]...)
如果你是用Haskell写的,它支持curry,你的代码应该是正确的;但是在JavaScript中,f(x)(y)
和f(x, y)
是不一样的。
你也不要从Redis success函数内部调用callback
,这也会打乱你的计时。
您应该使用async.waterfall
而不是async.series
来获得第二个函数的第一个函数结果
按序列运行任务函数数组,每个函数将其结果传递给数组中的下一个函数。但是,如果任何任务将错误传递给它们自己的回调函数,则下一个函数不会执行,并且会立即调用主回调函数并伴有错误。
并且,你的代码中有一个大错误。如果我理解你的代码,你想去第二个函数后修改所有的结果,并返回这个为第二个函数,对吗?在这种情况下,使用async.each
而不是result.forEach
,并在async each之后调用回调:
function search(client_id, callback) {
clientRedis.keys('director:*', function (err, results) {
var savedElems = [];
async.each(results, function (key, done) {
clientRedis.hgetall(key, function (err, obj) {
if (err) {
return done(err);
}
savedElems.push(obj);
done();
});
}, function (err) {
if (err) {
return callback(err);
}
callback(null, savedElems);
});
});
}