Разрыв динамической последовательности обещаний с помощью Q

#javascript #promise #q

#javascript #обещание #q

Вопрос:

У меня есть несколько обещаний (P1, P2, … Pn) Я хотел бы связать их в последовательность (так что Q.all не вариант), и я хотел бы разорвать цепочку при первой ошибке.
Каждое обещание поставляется со своими собственными параметрами.
И я хотел бы перехватывать каждую ошибку обещания, чтобы удалить ошибку.

Если P1, P2, .. PN — это мои обещания, я понятия не имею, как автоматизировать последовательность.

Ответ №1:

Если у вас есть цепочка обещаний, все они уже запущены, и вы ничего не можете сделать, чтобы запустить или остановить какое-либо из них (вы можете отменить, но на этом все заканчивается).

Предполагая, что у вас есть F1,... Fn функции, возвращающие обещания, вы можете использовать для этого базовый строительный блок promises, our .then :

 var promises = /* where you get them, assuming array */;
// reduce the promise function into a single chain
var result = promises.reduce(function(accum, cur){
    return accum.then(cur); // pass the next function as the `.then` handler,
                     // it will accept as its parameter the last one's return value
}, Q()); // use an empty resolved promise for an initial value

result.then(function(res){
    // all of the promises fulfilled, res contains the aggregated return value
}).catch(function(err){
    // one of the promises failed, 
    //this will be called with err being the _first_ error like you requested
});
  

Таким образом, менее аннотированная версия:

 var res = promises.reduce(function(accum,cur){ return accum.then(cur); },Q());

res.then(function(res){
   // handle success
}).catch(function(err){
   // handle failure
});
  

Комментарии:

1. Спасибо! Однако, я полагаю, что «агрегированный результат», переданный в качестве аргумента в последнем «тогда», — это то, что я должен реализовать сам в соответствии с моим собственным удобством?

2. @Guid Это зависит от вашего API, я предположил, что для каждого обещания требуется результат предыдущего (поскольку вы просили их последовательно). Вы могли бы, например, создать массив снаружи и push добавить его в часть цикла (перед return accum.then(cur); ), а затем .return результаты.