我的async.series有什么问题

时间:2014-04-05 10:40:03

标签: javascript node.js asynchronous

我正在尝试使用https://github.com/caolan/async#series

在nodejs中执行异步系列
async.series([
    function getLightsId(callback) {
        args = {
            path: {
                "username": "username"
            }
        };

        client.registerMethod("getLightState", "http://bridgeip/api/${username}/lights/", "GET");

        client.methods.getLightState(args, function (data, response) {
            var ids = [];
            for (key in data) {
                ids.push(key);
            }
            callback(null, ids);
        });
    },
    function getLightsState(ids, callback) {
        var lightsState = new Object();
        async.each(ids, function (id) {
            getLightState(id, function (state) {
                lightsState[id] = state;
            });
        });
        callback(null, lightsState);
    }
], function (err, result) {
    console.log(result);
});

但它给我这个错误:

callback(null,lightsState); TypeError:undefined不是函数。

我不明白为什么......

如何将我的对象lightsState传递给我的其他函数?

2 个答案:

答案 0 :(得分:0)

您在第二项任务中不会获得ID,但您会收到文档中描述的回调。

你可以这样做:

async.series([
    function getLightsId(callback) {
        args = {
            path: {
                "username": "username"
            }
        };

        client.registerMethod("getLightState", "http://bridgeip/api/${username}/lights/", "GET");

        client.methods.getLightState(args, function (data, response) {
            var ids = [];
            for (key in data) {
                ids.push(key);
            }
            callback(null, ids);
        });
    },
], function (err, result) {
  var ids = result[0]
  var lightsState = new Object();
  async.each(ids, function (id) {
      getLightState(id, function (state) {
          lightsState[id] = state;
      });
  });
});

但这与async.series的传统用例相反,你只有一个异步任务 你追求的可能是async.waterfall - 所以这就是这样的:

async.waterfall([
    function getLightsId(callback) {
        args = {
            path: {
                "username": "username"
            }
        };

        client.registerMethod("getLightState", "http://bridgeip/api/${username}/lights/", "GET");

        client.methods.getLightState(args, function (data, response) {
            var ids = [];
            for (key in data) {
                ids.push(key);
            }
            callback(null, ids);
        });
    },
    function getLightsState(ids, callback) {
        var lightsState = new Object();
        async.each(ids, function (id) {
            getLightState(id, function (state) {
                lightsState[id] = state;
            });
        }, function(err) { 
          callback(err, lightsState)
        });
    }
], function (err, result) {
  console.log(result);
});

哦,我认为async.each需要回调。我不确定,也许你打算不这样做?

答案 1 :(得分:0)

  

它将此错误归还给我:callback(null, lightsState); TypeError : undefined is not a function.

因为callback不是函数。只传递给function getLightsState(ids, callback) {的第一个参数是一个。检查the docs for series

  

tasks - 包含要运行的函数的数组或对象,每个函数都传递一个    回调(错误,结果)   series(tasks)运行tasks数组中的函数,每个函数在前一个函数完成后运行。

相比之下,这些是docs for the waterfall function - 这就是你想要的:

  

运行系列的tasks数组,每个将结果传递给数组中的下一个


顺便说一下,

    var lightsState = new Object();
    async.each(ids, function (id) {
        getLightState(id, function (state) {
            lightsState[id] = state;
        });
    });
    callback(null, lightsState);

不太可行,您可能想要使用reduce代替:

async.reduce(ids, {}, function(lightsState, id, rcallback) {
    getLightState(id, function(state) {
        lightsState[id] = state;
        rcallback(null, lightsState);
    });
}, callback);