我有一个接受函数作为回调参数的方法。外部方法和回调函数都返回我收集到数组的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'方法以及如何避免这种情况?
感谢您的回复!
答案 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);
}