将已解决的承诺值传递到最终“然后”链的最佳方法是什么?

What is the best way to pass resolved promise values down to a final "then" chain

本文关键字:然后 最佳 方法 是什么 承诺 解决 值传      更新时间:2023-09-26

我正在尝试使用 node.js中的 Q 模块来了解承诺,但是我有一个小问题。

在此示例中:

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*/);

.create 方法返回一个承诺,然后在每个 .then() 中,正如预期的那样,人们会得到承诺的解析值。

但是在最后的 .then() 中,我需要拥有所有 3 个先前解析的承诺值。

最好的

方法是什么?

这些是你的许多选项中的一些:

在门 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
});

在门 2 后面,将累积的模型打包成一个阵列,然后展开包装。

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*/);

在门 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
});

蓝鸟承诺库通过.bind()提供了另一种解决方案。

它看起来像这样:

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;
});

文档中有很多关于此方法的有趣信息。

您可能不需要等到创建模型 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 :(
});

这样做的是:

  • 创建一系列承诺,您需要的每个模型都有一个承诺;
  • 并行执行所有 3 个承诺;
  • 当所有 3 个承诺都完成后,执行在 spread() 中传递的函数。参数是声明顺序中每个承诺的解析值。

我希望它对你有所帮助:)

相关文章: