Выбор ответа Middle Промисы и async/await обновлено

Исключение в таймере внутри промиса

Вопрос

Поймает ли catch ошибку?

new Promise(() => {
  setTimeout(() => {
    throw new Error('сбой');
  }, 0);
}).catch((e) => console.log('поймано', e.message));

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Нет: ошибка брошена в другой задаче, вне executor, а промис застрянет в pending. Промис превращает в отклонение только исключения, брошенные синхронно внутри executor.

Варианты ответа

  1. Да: промис отклонится, и catch выведет поймано сбой через секунду
  2. Нет: ошибка брошена в другой задаче, вне executor, а промис застрянет в pendingправильный ответ
  3. Да, но только в браузере: там ошибки таймеров попадают в ближайший промис
  4. Нет, потому что executor не вызвал reject, и сам код таймера не запустится

Разбор

Промис превращает в отклонение только исключения, брошенные синхронно внутри executor. Колбэк таймера выполняется позже, отдельной задачей, когда executor давно завершился, и промис о нём ничего не знает. Ошибка станет неперехваченной (в Node это падение процесса), а промис так и останется в pending. Правильно: вызывать reject(new Error(...)) внутри колбэка таймера. Код при этом выполняется, reject вызывать не обязательно.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме