Тривиальное (но неэлегантное и довольно ошибочное) решение состоит в том, чтобы просто использовать переменные более высокого уровня (к которым все обратные вызовы в цепочке имеют доступ) и записывать в них значения результата, когда вы получить их:
function getExample() {
var resultA;
return promiseA(…).then(function(_resultA) {
resultA = _resultA;
// some processing
return promiseB(…);
}).then(function(resultB) {
// more processing
return // something using both resultA and resultB
});
}
Вместо многих переменных можно также использовать (первоначально пустой) объект, на котором результаты сохраняются как динамически созданные свойства.
Это решение имеет несколько Недостатки:
Библиотека Bluebird поощряет использование объекта, который передается вместе с использованием метода bind()
, чтобы назначить объект контекста цепочке обещаний. Он будет доступен из каждой функции обратного вызова через непригодное для использования this
ключевое слово . Хотя свойства объекта более подвержены необнаруженным опечаткам, чем переменные, шаблон довольно умный:
function getExample() {
return promiseA(…)
.bind({}) // Bluebird only!
.then(function(resultA) {
this.resultA = resultA;
// some processing
return promiseB(…);
}).then(function(resultB) {
// more processing
return // something using both this.resultA and resultB
}).bind(); // don't forget to unbind the object if you don't want the
// caller to access it
}
Этот подход можно легко моделировать в библиотеках обещаний, которые не поддерживают .bind (хотя в несколько более подробных путь и не может использоваться в выражении):
function getExample() {
var ctx = {};
return promiseA(…)
.then(function(resultA) {
this.resultA = resultA;
// some processing
return promiseB(…);
}.bind(ctx)).then(function(resultB) {
// more processing
return // something using both this.resultA and resultB
}.bind(ctx));
}