Как бороться с зависанием промисов?

Всем привет. Недавно столкнулся с ситуацией, когда что-то синхронное в промисе зависает или зацикливается, вся асинхронность улетает в никуда. Для примера, иллюстрирующего эту ситуацию, я создал 2 промиса с синхронными лупами , которые гадят в консоль. В первом промисе предусмотрел таймер таймута на реджект, который кстати тоже не сработает.
Вопрос следующий, как бороться с подобными ситуациями?

пример кода:
const f1 = () => {
    return new Promise((resolve, reject) => {
        setTimeout(reject, 3000, "timeout");
        while (true) {
            console.log(1);
        }
        resolve(ture);
    });
};

const f2 = () => {
    return new Promise((resolve, reject) => {
        while (true) {
            console.log(2);
        }
        resolve();
    })
};


f1();
f2();


В консоль до бесконечности будет лететь -> 1
  • Вопрос задан
  • 884 просмотра
Решения вопроса 1
@alexeyproject
По сути ваш код сводится к следующему:
while (true) {
    console.log(1);
}
и отсюда уже не выходит.
А если подробнее, то:
1. При вызове f1(), сразу в этом же eventloop (т.е. синхронно) начинает выполняться ее код
2. setTimeout-ом только планируем поставить через 100 мс в macrotask функцию на выполнение. А это какой-то из следующих eventloop-ов.
3. Попадаем в бесконечный while и отсюда уже не выходим.

Смотрите в этой статье Задачи, микрозадачи, очереди и планы, если хотите разобраться. К сожалению оригинал Tasks, microtasks, queues and schedules не доступен. Там был классный интерактивный пример.
По сути вызов асинхронной функции эквивалентен созданию промиса.
Что вы хотели сделать в примере не совсем понятно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
vitali1995
@vitali1995
Нужно каждую итерацию оборачивать в промис. Привожу пример, в котором есть интересный момент: циклы чередуются, но таймер не вызывается. Если разберётесь, почему, пишите.

async function asyncLog(items) {
   console.log(items);
}

async function f1() {
   setTimeout(() => {
      throw Error("timeout");
   }, 100);

   while (true) {
      await asyncLog(1);
   }
}

async function f2() {
   while (true) {
      await asyncLog(2);
   }
}

f1();
f2();
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы