Когда нужно возвращать вложенные обещания? - PullRequest
0 голосов
/ 26 ноября 2018

При объединении нескольких операторов then я изо всех сил пытаюсь понять, когда мне нужно вернуть значение следующему оператору then против того, когда оно автоматически передается.Путаница (для меня) заключается в том, что у меня есть обещание внутри оператора then вместо нет.

Это в среде узла - экспресс-приложение (точнее, функция Firebase, запускаемая HTTP-запросом)- поэтому я в конечном итоге res.send() определенное значение.

// Do I need to return mainFunction()?
mainFunction()
  .then(resultOfMyFunction => {
    // I want the next "then" to wait for the response from this block
    // Do I have to return asyncFunction() or just the value below?
    asyncFunction().then(resultOfPromise => {
      // Do I return resultOfPromise?
    }).catch(error => {
      // If I return this error, will it go to the mainFunction catch block?
      return error
    })
  }).then(resultOfPromise => {
    // This is blocking, so the next "then" should wait for the value
    return synchronousFunction(resultOfPromise)
  }).then(resultOfSynchronousFunction => {
    // End of function - do I need to return resultOfSynchronousFunction?
  }).catch(error => {
    // Do I need to return error?
  })

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

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

Вам не нужны анонимные функции в первых двух then()

Вы можете сделать это, передавая ссылки на функции в then() вместо

mainFunction()
  .then(asyncFunction)
  .then(synchronousFunction)
  .then(resultOfSynchronousFunction => {
    // consume resultOfSynchronousFunction or return to next then()
  }).catch(error => {
    // Do I need to return error?
    // only if this is not final catch block
  })
0 голосов
/ 26 ноября 2018

Путаница (для меня) заключается в том, что у меня есть обещание внутри оператора then, а не.

Всякий раз, когда у вас есть обещание внутри then или асинхронной функции, которую вы должны вернуться к нему.В противном случае отклонения (выданные ошибки в асинхронных функциях и обещаниях) сглатывают и попадают в глобальный хук, не давая возможности тому, кто вызывает ваш код для обработки ошибки.

Синхронные функции не имеют такого ограничения - возвращаяСинхронный код имеет значение только в том случае, если вы хотите повторно использовать его возвращаемое значение, поскольку сгенерированные ошибки обрабатываются then автоматически.

  // If I return this error, will it go to the mainFunction catch block?

Обещания действительно довольно не магические.Возвращаемое значение - это то, как состояние ошибки / успеха (отклонено / выполнено) распространяется между вызовами, поэтому, если вы не вернете значение, mainFunction не перейдет в свой блок catch.

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

0 голосов
/ 26 ноября 2018

Я думаю, вы хотите что-то подобное.Я предполагаю, что под This is blocking вы подразумеваете, что synchronousFunction не является асинхронным.В этом случае его не нужно использовать в обещании, подобном моде.

mainFunction()
  .then(resultOfMyFunction => {
    //return promise from async function
    return asyncFunction();
  })
  .then(resultOfPromise => {
    let resultOfSynchronousFunction = synchronousFunction(resultOfPromise);
    // End of function
  })
  .catch(error => {
    // Do I need to return error?
  });

, если вы хотите вернуть resultOfSynchronousFunction, тогда вы должны прочитать Как мне вернуть ответ от асинхронного вызова?

Если вы хотите вернуть асинхронную версию synchronousFunction, вам нужно заключить это в обещание:

mainFunction()
  .then(resultOfMyFunction => {
    //return promise from async function
    return asyncFunction();
  })
  .then(resultOfPromise => {
    return new Promise((resolve, reject) => {
       let resultOfSynchronousFunction = synchronousFunction(resultOfPromise);
       // End of function
       resolve(resultOfSynchronousFunction);
    });
  })
  .then(resultOfSynchronousFunction => {})
  .catch(error => {
    // Do I need to return error?
  });

Если вы хотите выполнить еще один асинхронный вызовпосле synchronousFunction лучший шаблон будет:

mainFunction()
  .then(resultOfMyFunction => {
    //return promise from async function
    return asyncFunction();
  })
  .then(resultOfPromise => {

       let resultOfSynchronousFunction = synchronousFunction(resultOfPromise);
       // End of function
       return anotherAsyncCall(resultOfSynchronousFunction );
  })
  .then(resultOfanotherAsyncCall => {})
  .catch(error => {
    // Do I need to return error?
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...