我目前正在努力控制承诺的流程(承诺新手!)。
我调用Redis返回一个数组对象。然后,我遍历每个结果并回调Redis以获取值,并希望将这些值填充到最终对象plot <- ggplot(data,aes(x=x,y=x)) +
geom_point()
。
out对象永远不会填充,因为forEach还没有完成,我猜测:
(注意Redis客户端lib返回基于when.js的promise作为默认值)
out
我如何保证forEach循环完整?
我已经阅读了很多类似的帖子(我知道这是重复的)但是却无法理解为什么内部的done()方法不包含完全完整的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));
obj。
我猜我需要将forEach包装在一个承诺中吗?欣赏任何方向。
更新1:非常感谢@David_Aurelio。我现在需要使用键和值填充out
。这是我的尝试:
out
内部console.log打印正确的键/值
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); });
现在最后完成打印:
key1 val1
key2 val2
答案 0 :(得分:0)
forEach
循环完成,但您在内创建的Promise不会。 when.js 实现Promises/A+规范,这保证promise回调的异步解析。这意味着,保证在当前调用堆栈完成执行后调用传递给then()
的回调。
您需要从then
- 回调中返回一个承诺,以便将内部承诺连接到外部承诺。更具体地说,你需要承诺所有内心的承诺。
最简单的方法是使用when.all
:
REDISCLIENT.keys("apikey:*")
.then(function (replies) {
return when.all(replies.map(function (key, index) {
return REDISCLIENT.get(key);
}));
})
.catch(console.log)
.done(function (out) {console.log(out); });
在原始代码中,您也不会将回调注册到done
,而是在第一个承诺解决之前立即致电console.log(out)
。
答案 1 :(得分:0)
了解流量控制和由承诺链传达的数据非常重要,具体取决于:
when.all()
这里是如何通过out
作为内部成员来实现您想要的目标。
REDISCLIENT.keys("apikey:*")
.then(function (replies) {
var out = {}: //<<<<< initiate `out` as an inner member
return when.all(replies.map(function (key, index) { //<<<<< here's David Aurelio's when.all(replies.map(...))
return REDISCLIENT.get(key).then(function (value) { //<<<<< `return` here causes `.map()` to build an array of promises.
out[key] = value;
});
})).then(function() { //<<<< here's an additional `.then()` chained to `when.all(...)`
return out; //<<<<< `return` here makes the populated `out` available to the `.done()` callback below.
});
})
.catch(console.log)
.done(function (out_) {
console.log(out_);
});
丑陋的外围成员已经消失了!
在.done()
回调中,我已将成员名称更改为out_
,以强调由于return out
而传递,当所有 [geddit] REDISCLIENT.get()
次呼叫返回的承诺成功结算时,只发生。