我在我的项目中使用了异步库,最终出现了一个奇怪的行为:我的一些参数在我的调用中是“未定义的”。
例如(这不是我的实际代码,但行为是相同的,以这种方式公开我的问题更简单):
var token;
async.series([
function getToken (done) {
api.getToken(userId, function (err, data) {
if (err) return done(err);
token = data;
return done();
}
},
async.apply(doSomethingWithTheToken, token)
], callback);
当调用我的函数“doSomethingWithTheToken”时,作为参数传递的标记具有“未定义”值,即使我在之前的函数“getToken”中更改了它。
但如果我这样做:
var token;
async.series([
function getToken (done) {
api.getToken(userId, function (err, data) {
if (err) return done(err);
token = data;
return done();
}
},
function doSomething (done) {
doSomethingWithTheToken(token, done);
}
], callback);
然后,在函数“doSomethingWithTheToken”中传递的令牌没有问题,前一个函数给出了正确的值。
我在编写这篇文章之前已经在async模块中做了一些研究,当我显示传递给async.apply函数的参数时,出乎意料的是它们会在async.series流程中进行任何函数调用之前显示 - 这解释了我的令牌值为“未定义”的原因。
有人能够解释我为什么会发生这种情况吗?
我希望我对自己的问题很清楚 提前致谢
答案 0 :(得分:2)
每当调用async.series时,它都会在数组中准备其所有函数引用, 它在数组中添加了getToken, 然后调用async.apply并在数组中添加生成的函数引用(async.apply的输出)。
当时令牌未定义。
这里发生的情景如下:
> var i;
> var arr = [1,2,3,i,5,6];
> i=4;
> arr
[ 1, 2, 3, undefined, 5, 6 ]
希望你明白这一点。
答案 1 :(得分:2)
正如其他答案中所述:目前async.apply
被称为token
是undefined
。
您可能希望查看async.waterfall
,但它允许您将参数传递给序列中的下一个函数,这样您就可以执行此操作:
async.waterfall([
function getToken (done) {
api.getToken(userId, function (err, data) {
if (err) return done(err);
return done(null, data);
});
},
function doSomething (token, done) {
doSomethingWithTheToken(token, done);
}
], callback);
事实上,您可以将其缩短为此(如果doSomethingWithTheToken
接受token
和done
作为参数):
async.waterfall([
function getToken (done) {
api.getToken(userId, done);
},
doSomethingWithTheToken
], callback);