Разница между "return await promise" и " return promise`

учитывая приведенные ниже примеры кода, есть ли разница в поведении, и если да, то каковы эти различия?

return await promise

async function delay1Second() {
  return (await delay(1000));
}

return promise

async function delay1Second() {
  return delay(1000);
}

как я понимаю, первый будет иметь обработку ошибок в асинхронной функции, и ошибки будут пузыриться из обещания асинхронной функции. Однако для второго потребуется на один тик меньше. Правильно ли это?

этот фрагмент просто общий функция для возврата обещания Для справки.

function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

2 ответов


большую часть времени нет заметной разницы между return и return await. Обе версии delay1Second имеют точно такое же наблюдаемое поведение (но в зависимости от реализации,return await версия может использовать немного больше памяти, так как промежуточный Promise объект может быть создан).

однако, как указал @PitaJ, есть один случай, когда есть разница: если return или return await вложен в тег try-catch блок. Считать это пример

async function rejectionWithReturnAwait () {
  try {
    return await Promise.reject(new Error())
  } catch (e) {
    return 'Saved!'
  }
}

async function rejectionWithReturn () {
  try {
    return Promise.reject(new Error())
  } catch (e) {
    return 'Saved!'
  }
}

в первой версии асинхронная функция ожидает отклоненного обещания перед возвращением его результата, что приводит к тому, что отклонение превращается в исключение и catch предложение будет достигнуто; таким образом, функция вернет обещание, разрешающее строку "сохранено!".

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


это трудный вопрос для ответа, потому что это зависит на практике от того, как ваш транспилер (возможно babel) фактически выводит async/await. Вещи, которые ясны независимо:

  • обе реализации должны вести себя одинаково, хотя первая реализация мая еще меньше Promise в цепи.

  • особенно, если вы отбросите ненужное await, вторая версия не потребовала бы никакого дополнительного кода от transpiler, а первая нет.

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