node.js 将已解决的承诺值传递到最终的“then”链的最佳方法是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18849312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to pass resolved promise values down to a final "then" chain
提问by MoSs
I'm trying to get my head around promises, using the Q module in node.js, however I have a small issue.
我正在尝试使用 node.js 中的 Q 模块来解决承诺,但是我有一个小问题。
In this example:
在这个例子中:
ModelA.create(/* params */)
.then(function(modelA){
return ModelB.create(/* params */);
})
.then(function(modelB){
return ModelC.create(/* params */);
})
.then(function(modelC){
// need to do stuff with modelA, modelB and modelC
})
.fail(/*do failure stuff*/);
The .create method returns a promise then in each .then(), as expected one gets the resolved value of the promise.
.create 方法在每个 .then() 中返回一个承诺 then,正如预期的那样,一个人获得了承诺的解析值。
However in the final .then() I need to have all 3 previously resolved promise values.
然而,在最终的 .then() 中,我需要拥有所有 3 个先前已解决的承诺值。
What would be the best way to do this?
什么是最好的方法来做到这一点?
回答by Kris Kowal
These are some of your many options:
这些是您的众多选择中的一些:
Behind door 1, use reduce to accumulate the results in series.
在门 1 后面,使用 reduce 来累积结果。
var models = [];
[
function () {
return ModelA.create(/*...*/);
},
function () {
return ModelB.create(/*...*/);
},
function () {
return ModelC.create(/*...*/);
}
].reduce(function (ready, makeModel) {
return ready.then(function () {
return makeModel().then(function (model) {
models.push(model);
});
});
}, Q())
.catch(function (error) {
// handle errors
});
Behind door 2, pack the accumulated models into an array, and unpack with spread.
在 2 号门后,将累积的模型打包成一个数组,并用spread 解包。
Q.try(function () {
return ModelA.create(/* params */)
})
.then(function(modelA){
return [modelA, ModelB.create(/* params */)];
})
.spread(function(modelA, modelB){
return [modelA, modelB, ModelC.create(/* params */)];
})
.spread(function(modelA, modelB, modelC){
// need to do stuff with modelA, modelB and modelC
})
.catch(/*do failure stuff*/);
Behind door 3, capture the results in the parent scope:
在 3 号门后,捕获父作用域中的结果:
var models [];
ModelA.create(/* params */)
.then(function(modelA){
models.push(modelA);
return ModelB.create(/* params */);
})
.then(function(modelB){
models.push(modelB);
return ModelC.create(/* params */);
})
.then(function(modelC){
models.push(modelC);
// need to do stuff with models
})
.catch(function (error) {
// handle error
});
回答by justmoon
The Bluebirdpromises library provides another solution for this via .bind().
在蓝鸟承诺库提供了这种通过其他的解决方案.bind()。
It looks like this:
它看起来像这样:
ModelA.create(/* params */).bind({})
.then(function (modelA) {
this.modelA = modelA;
return ModelB.create(/* params */);
})
.then(function (modelB) {
this.modelB = modelB;
return ModelC.create(/* params */);
})
.then(function (modelC) {
// you have access to this.modelA, this.modelB and modelC;
});
There is a lot of interesting information about this method in the documentation.
文档中有很多关于此方法的有趣信息。
回答by gustavohenke
You probably doesn't need to wait until modelA is created to create modelB and so on.
If this is true, then you can do the following:
您可能不需要等到创建模型 A 来创建模型 B 等等。
如果这是真的,那么您可以执行以下操作:
var promises = [
ModelA.create(...),
ModelB.create(...),
ModelC.create(...)
);
Q.all( promises ).spread(function( modelA, modelB, modelC ) {
// Do things with them!
}).fail(function() {
// Oh noes :(
});
What this does is:
它的作用是:
- Create an array of promises, with one promise for each model you need;
- Execute all 3 promises in parallel;
- Execute a function passed in
spread()when all 3 promises are done. The arguments are the resolved values for each promise, in the declaration order.
- 创建一系列承诺,为您需要的每个模型提供一个承诺;
- 并行执行所有 3 个 promise;
spread()当所有 3 个承诺都完成时执行传入的函数。参数是声明顺序中每个承诺的解析值。
I hope it helps you :)
我希望它可以帮助你:)

