Отмените следующее обещание, если предыдущее не удалось (синхронно) - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть случай, когда я отправляю письмо, если предыдущее действие было успешным.

Promise.all([doSomeAction(), sendMailIfSuccess()]) // both of them are promises
   .then(() => success)
   .catch(() => err);

Однако, если обещание doSomeAction() не выполнено до разрешения sendMailIfSuccess, почта отправляется в любом случае. Но это не должно.

Вопрос : Как вызвать sendMailIfSuccess обещание, только если doSomeAction разрешено? Обещание sendMailIfSuccess должно дождаться обещания doSomeAction.

Ответы [ 3 ]

4 голосов
/ 19 апреля 2020

Поскольку вы хотите запускать эти два процесса последовательно и запускать второй только в случае успешного выполнения первого шага, Promise.all здесь не тот инструмент - просто используйте вместо него .then:

doSomeAction()
  .then(() => sendMailIfSuccess())
  .catch( /* handle errors, including doSomeAction failures */);
0 голосов
/ 19 апреля 2020

Как упомянуто @CertainPerformance, если вы хотите, чтобы эти методы запускались последовательно. Вы должны вызвать второй метод после получения успешного ответа от первого.

doSomeAction()
  .then(res => {
    /* do something with the res, if needed */
    return sendMailIfSuccess();
  })
  .catch(err => {
    /* handle errors */
  });

Почему Promise.all(...) не был правильным выбором? Как уже упоминалось здесь

Обычно он используется после одновременного запуска нескольких асинхронных задач и создания обещаний для их результатов, так что можно дождаться завершения всех задач .

Точно так же здесь есть Promise.race(...) , который используется, когда нам нужно первое разрешение или отклонение в итерируемом.

0 голосов
/ 19 апреля 2020

Вы также можете использовать async/await

async function f(){
  let result1 = await doSomeAction()
  let result2 = await sendMailIfSuccess()
}

try {
 f()
} catch(err) {
 //handle error
}
...