【发布时间】:2015-07-19 22:06:07
【问题描述】:
我目前正在努力处理 promise 的控制流程(promise newbie!)。
我调用了返回一个数组对象的 Redis。然后我遍历每个结果并回调 Redis 以获取一个值,并希望将这些填充到最终对象 out。
out 对象永远不会被填充,我猜测 forEach 还没有完成:
(注意 Redis 客户端库默认返回基于 when.js 的承诺)
var out = {};
REDISCLIENT.keys("apikey:*")
.then(function (replies) {
replies.forEach(function (key, index) {
REDISCLIENT.get(key)
.then(function (value) {
out[key] = value;
})
.done(console.log(out));
});
})
.catch(console.log)
.done(console.log(out));
如何保证 forEach 循环是完整的?
我已经阅读了许多类似的帖子(我知道这是重复的)但是无法理解为什么内部的 done() 方法不包含完整的out obj。
我猜我需要将 forEach 本身包装在一个承诺中?欣赏任何方向。
更新 1:非常感谢@David_Aurelio。我现在需要用键和值填充out。这是我的尝试:
GLOBAL.REDISCLIENT.keys("apikey:*")
.then(function (replies) {
return when.all(replies.map(function (key, index) {
return GLOBAL.REDISCLIENT.get(key)
.then(function (val) {
out[key] = val;
console.log(key, val);
});
}));
})
.catch(console.log)
.done(function (out) {console.log(out); });
内部 console.log 打印正确的键/值
key1 val1
key2 val2
最后完成的现在打印:
[ undefined, undefined ]
【问题讨论】:
-
您神奇地期望外部promise 知道内部代码何时完成,但是您没有在它们之间建立任何联系,因此外部promise 不会等待内部promise 完成。因此,当您尝试在代码的最后一行记录
out的值时,还没有完成任何内部代码。我不知道when-js,但是您必须创建一个主promise,当您完成所有内部promise 时解决该promise 并从外部.then()处理程序返回它。这将告诉外部承诺等待所有内部活动完成。 -
您会得到
[undefined, undefined],因为.done 回调中的out不是填充的out对象。简单的解决方案是.done(function () {console.log(out); });,它确保记录最初定义的out。但是,请参阅下面的答案。
标签: javascript node.js foreach promise when-js