Подтвердить что ты не робот

Каков наилучший способ передачи разрешенных значений обещаний до конечной "затем" цепочки

Я пытаюсь обойти promises, используя Q-модуль в node.js, однако у меня небольшая проблема.

В этом примере:

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 ранее разрешенных значения обещания.

Каким будет лучший способ сделать это?

4b9b3361

Ответ 1

Вот некоторые из ваших многочисленных опций:

За дверью 1 используйте сокращение, чтобы скопировать результаты последовательно.

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

Ответ 2

Библиотека Bluebird promises предоставляет другое решение для этого через .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;
});

В документации имеется много интересной информации об этом методе.

Ответ 3

Вероятно, вам не нужно ждать, пока будет создан modelA для создания модели и т.д.
Если это так, вы можете сделать следующее:

var promises = [
  ModelA.create(...),
  ModelB.create(...),
  ModelC.create(...)
);

Q.all( promises ).spread(function( modelA, modelB, modelC ) {
  // Do things with them!
}).fail(function() {
  // Oh noes :(
});

Что это такое:

  • Создайте массив promises с одним обещанием для каждой модели, которая вам нужна;
  • Параллельно выполнить все 3 promises;
  • Выполните функцию, переданную в spread(), когда все 3 promises выполнены. Аргументы - это разрешенные значения для каждого обещания в порядке объявления.

Надеюсь, это вам поможет:)