从方法返回的Promise未定义

时间:2016-02-18 10:45:12

标签: javascript node.js promise

我有一个接受函数作为回调参数的方法。外部方法和回调函数都返回我收集到数组的promises,等待它们用Q.all解析。

function eval() {
    var colReadPromisses = [];

    config.mongodb.colls.forEach(function (collName) {

        var outer = mongo.readCollection(collName,
                function (jsonData) {
                    var prom = es.pushItemToES(jsonData, esIndexName, collName, i);
                    colReadPromisses.push(prom);
                });
        colReadPromisses.push(outer);
    });

    return Q.all(colReadPromisses);
}

现在,内部回调方法被多次调用,并且需要一些时间来处理所有这些方法。当他们正在处理时,承诺从' readCollection'方法得到“未定义”'导致Q.all(colReadPromisses);'解决。

所以我的两个问题就是为什么nodejs会失去追踪来自' readCollection'方法以及如何避免这种情况?

感谢您的回复!

2 个答案:

答案 0 :(得分:1)

我假设您想要在返回的承诺中获取readCollection和pushItemToES的结果

function eval() {

    return Q.all(config.mongodb.colls.map(function (collName) {

        var pushPromisses = [mongo.readCollection(collName, function (jsonData) {
            pushPromisses.push(es.pushItemToES(jsonData, esIndexName, collName, i));
        })];

        return pushPromisses[0] // once the outer promise resolves
        .then(function() {
            return Q.all(pushPromisses); // wait for them all (including the outer)
        });

    }));
}

解决后返回的promise将解析为二维数组

  • [0][0]将是mongo.readCollection(colls[0])
  • 的结果
  • [0][1..n]将是来自pushItemToES
  • 的每个readCollection(colls[0])的结果
  • [1][0] will be the result of the mongo.readCollection(colls [1])'
  • [1][1..n]将是来自pushItemToES
  • 的每个readCollection(colls[1])的结果

等等

如果您在退回的承诺中不需要mongo.readCollection的结果

function eval() {

    return Q.all(config.mongodb.colls.map(function (collName) {

        var pushPromisses = [];

        return mongo.readCollection(collName, function (jsonData) {
            pushPromisses.push(es.pushItemToES(jsonData, esIndexName, collName, i));
        }).then(function() {
            return Q.all(pushPromisses);
        });

    }));
}

在这种情况下,返回的promise仍然是二维的,但仅包含pushItemToES的结果

  • [0][0..n]将是来自pushItemToES
  • 的每个readCollection(colls[0])的结果
  • [1][0..n]将是来自pushItemToES
  • 的每个readCollection(colls[1])的结果

我无法在已解决的承诺中看到二维数组的任何方式 - 因为es.pushItemToES未被称为"已知" (至少没有提前)次数

答案 1 :(得分:0)

您必须重新组织代码:

function eval() {
    // replace forEach with map
    var colReadPromisses = config.mongodb.colls.map(function (collName) {

           // return pushItemToES promises
            return new Promise(function(resolve) {
                mongo.readCollection(collName,
                    function (jsonData) {
                        resolve(es.pushItemToES(jsonData, esIndexName, collName, i));                   
                    });
            });

    });

    // colReadPromisses stores array of pushItemToES promises
    return Q.all(colReadPromisses);
}
相关问题