Sobes.tech
Middle
30

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

Сұралған компаниялар
X5 techX5 tech

AI-дан жауап

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, что нарушит логику работы.