Вызов синхронной функции в асинхронной функции - PullRequest
1 голос
/ 11 января 2020

У меня проблемы с пониманием работы функции asyn c в JavaScript. Давайте возьмем код ниже:

async () => {
      console.log(1);
      setTimeout(() => console.log(2)
        , 2000)
      console.log(3);
}

Я ожидаю, что вызов синхронной функции внутри asyn c должен заблокировать поток перед выполнением следующего кода. Так что я ожидаю получить 1 -> 2 -> 3, вместо этого я получаю 1 -> 3 -> 2. Не могу найти объяснение, почему это происходит и как заблокировать поток для получения вывода 1 -> 2 -> 3. Я использую Node 12 с безсерверным фреймворком.

Ответы [ 2 ]

1 голос
/ 11 января 2020

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

Это делает

Так что я ' я ожидаю получить 1 -> 2 -> 3 вместо этого я получаю 1 -> 3 -> 2.

setTimeout является не синхронным. Это очень явно для постановки в очередь функции для запуска позже, по прошествии некоторого времени.

Не могу найти объяснение, почему это происходит и как заблокировать поток для получения вывода 1 -> 2 -> 3.

Сам по себе вы не можете.

Самое близкое, на что вы могли бы прийти, это заменить setTimeout на al oop, который кружится по кругу, пока какое-то время прошло ... но это было бы ужасно (это заблокировало бы интерфейс для начинающих).

Если вы хотите просто запустить три журнала по порядку, то замените setTimeout на что-то, что возвращает обещание, а затем await it (который перевел бы функцию asyn c в спящий режим и позволил бы любому другому коду продолжать работать, пока обещание не будет выполнено).

const timeout = function() {
  return new Promise(function(res) {
    setTimeout(() => {
      console.log(2);
      res();
    }, 2000)
  })
};


const x = async() => {
  console.log(1);
  await timeout();
  console.log(3);
}

x();
1 голос
/ 11 января 2020

async сам не будет ждать, пока выполнение setTimeout завершится, как вы ожидаете. Как вы можете прочитать из документации - найдите здесь для async:

Асинхронная c функция может содержать выражение await, которое приостанавливает выполнение асинхронной c функция для ожидания принятого разрешения Promise, затем возобновляет выполнение функции async и оценивается как разрешенное значение.

Просто построил быстрый пример, чтобы увидеть разницу между async и await решение и просто используйте setTimeout, как в вашем примере.

Рассмотрим следующий пример:

const getPromise = async () => {
  return new Promise((resolve) => {
    setTimeout(resolve, 3000);
  });
}

const run = async () => {
  console.log('run started');
  setTimeout(() => console.log('setTimeout finised'), 2000);
  console.log('setTimeout started');
  const promise = await getPromise();
  console.log('Promise resolved');
  console.log('run finished');
}

run();

Поясненные шаги:

  1. Регистрация этой функции run выполнение началось
  2. Присоединение события к setTimeout, которое будет завершится через ~ 2 секунды
  3. Войдите в консоль, чтобы setTimeout запустил
  4. Создание обещания с функцией getPromise и с ключевым словом await ожидало до resolve
  5. Через ~ 2 секунды setTimeout регистрирует, что это было завершено
  6. Через ~ 3 секунды из Promise функция resolve, вызываемая
  7. run, завершает свое выполнение после resolve и ведение журнала.

Надеюсь, это поможет вам понять эту часть кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...