Полезно ли ждать последней инструкции - PullRequest
2 голосов
/ 28 марта 2019

Я видел следующий код и задавался вопросом, полезно ли помимо указания метода для ключевого слова async указать ожидание в последней инструкции? Пример * +1002 *

async example(){
  //... whatever code

  //Last instruction
  await functionReturningAPromise()
}

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

async example(){
  //... whatever code

  //Last instruction
  return await functionReturningAPromise() //Is this useful ? or should we return directly
}

Лично я не вижу особого интереса.

Ответы [ 4 ]

2 голосов
/ 29 марта 2019

Имеет смысл, если вы хотите заключить последнюю инструкцию в блок try-catch для обработки ошибок.

async example(){
  //... whatever code

  //Last instruction
  try {

   return await functionReturningAPromise()
  } catch(error) {
     // error handling
  }
}

Если нет, добавление await сразу после return просто вводит ненужное обещание, но дает тот же результат.


Без использования return itПолезно использовать await в том случае, если вы хотите убедиться, что код, который выполняется после вашего вызова example(), не будет вызываться до расчета functionReturningAPromise().

1 голос
/ 29 марта 2019

Другие ответы (о try / catch) интересны. Это также имеет смысл, потому что он изменяет трассировку стека функции, если функция внутри нее выбрасывает.

То есть example будет отображаться в трассировке стека, если вы ожидаете functionReturningAPromise внутри него, и не будет, если вы этого не сделаете. Так что, если вам нравится возможность отладки кода, я рекомендую оставить в ожидании. =

1 голос
/ 29 марта 2019

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

async function doStuff() {
    await thingOne();
    await thingTwo();
    thingThree(); //You can put await here if you want to, but it's not necessary, 
                  //even if it is asynchronous / returns a Promise
}
0 голосов
/ 29 марта 2019

Так что это моя попытка ответить на мой собственный вопрос только с помощью кода. Мои выводы

1) Я бы не согласился с утверждением, что return await является избыточным вне блоков try / catch. Это изменит возвращаемое значение example(), если вызвано с await

2) Помещение await в последнем утверждении гарантирует, что если I await example() что-либо вызванное будет выполнено после того, как functionReturningAPromise() разрешится (как указывал @Kristianmitk).

3) Вызов асинхронной функции с помощью await действительно НЕ работает как Promise.all, если внутри нее запущено несколько обещаний (а не внутри await).

См. Результаты тестов. 3/4/5 Я получаю журнал медленной асинхронной функции после Я получаю результат.

function asyncSlow(testName){
  return new Promise(resolve => {
      setTimeout(() => {
        console.log('slow is done from' + testName)
        resolve('slow-' + testName);
      }, 300);
    });
}

function asyncFast(testName){
  return new Promise(resolve => {
      setTimeout(() => {
        console.log('fast is done from' + testName)
        resolve('fast-' + testName);
      }, 100);
    });
}

async function test1(){
  await asyncSlow('test1')
  await asyncFast('test1')
}

async function test2(){
  await asyncSlow('test2')
  return await asyncFast('test2')
}

async function test3(){
  asyncSlow('test3')
  return await asyncFast('test3')
}

async function test4(){
  asyncSlow('test4')
  return asyncFast('test4')
}

async function test5(){
  asyncSlow('test5')
  asyncFast('test5')
}

async function main(){
  const res = await test1()
  console.log('res = ' + res)
  
  const res2 = await test2()
  console.log('res2 = ' + res2)
  
  const res3 = await test3()
  console.log('res3 = ' + res3)
  
  const res4 = await test4()
  console.log('res4 = ' + res4)
  
  const res5 = await test5()
  console.log('res5 = ' + res5)
}

main()

А вот как выглядит результат:

slow is done fromtest1
fast is done fromtest1
res = undefined
slow is done fromtest2
fast is done fromtest2
res2 = fast-test2
fast is done fromtest3
res3 = fast-test3
fast is done fromtest4
res4 = fast-test4
res5 = undefined
slow is done fromtest3
fast is done fromtest5
slow is done fromtest4
slow is done fromtest5
...