Sobes.tech
Назад к вопросам
Middle
3

Зачем мы храним timeoutId? Что произойдёт, если Promise выполнится раньше таймаута, а потом сработает setTimeout с reject?

Компании, где спрашивали
X5 techX5 tech

Ответ от нейросети

sobes.tech AI

Мы храним timeoutId, чтобы иметь возможность отменить отложенное выполнение функции, например, вызов reject через setTimeout. Если Promise выполнится раньше таймаута (например, вызовется resolve), а потом сработает setTimeout с reject, то без отмены таймаута reject всё равно вызовется, что может привести к нежелательному изменению состояния или ошибкам.

Поэтому после успешного выполнения Promise (resolve или reject) нужно вызвать clearTimeout(timeoutId), чтобы предотвратить последующий вызов reject из таймаута.

Пример:

function withTimeout(promise, ms) {
  let timeoutId;
  const timeoutPromise = new Promise((_, reject) => {
    timeoutId = setTimeout(() => reject(new Error('Timeout')), ms);
  });

  return Promise.race([
    promise.finally(() => clearTimeout(timeoutId)),
    timeoutPromise
  ]);
}

Без хранения и очистки timeoutId может произойти ситуация, когда Promise уже выполнен, но таймаут всё равно вызовет reject, что нарушит логику работы.