在async.series中使用async.apply的未定义参数

时间:2016-04-06 12:48:50

标签: javascript node.js asynchronous

我在我的项目中使用了异步库,最终出现了一个奇怪的行为:我的一些参数在我的调用中是“未定义的”。

例如(这不是我的实际代码,但行为是相同的,以这种方式公开我的问题更简单):

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流程中进行任何函数调用之前显示 - 这解释了我的令牌值为“未定义”的原因。

有人能够解释我为什么会发生这种情况吗?

我希望我对自己的问题很清楚 提前致谢

2 个答案:

答案 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被称为tokenundefined

您可能希望查看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接受tokendone作为参数):

async.waterfall([
    function getToken (done) {
        api.getToken(userId, done);
    },
    doSomethingWithTheToken
  ], callback);