Javascript ожидают / асинхронный порядок выполнения - PullRequest
3 голосов
/ 15 мая 2019

Так что я пытаюсь обернуть голову об обещаниях / ожидании / асинхронности.Я не могу понять, почему, когда go () выполняется предупреждение с "готовым" идти сразу после console.log (кофе).Почему он только ожидает getCoffee (), а другие вызовы axios запускаются после «готового» предупреждения, когда все функции используют await / promises?

function getCoffee() {
  return new Promise(resolve => {
    setTimeout(() => resolve("☕"), 2000); // it takes 2 seconds to make coffee
  });
}
async function go() {
  try {
    alert("ok");
    const coffee = await getCoffee();

    console.log(coffee); // ☕

    const wes = await axios("https://randomuser.me/api/?results=200");
    console.log("wes"); // using string instead of value for brevity

    const wordPromise = axios("https://randomuser.me/api/?results=200");
    console.log("wordPromise"); // using string instead of value for brevity

    alert("finish");
  } catch (e) {
    console.error(e); // ?
  }
}
go();
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Асинхронное / ожидание работает как задумано. Просто для обновления консоли требуется некоторое время или перерисовка браузера, поэтому alert запускается до того, как сможет перерисоваться. Вы можете проверить это, используя все alert вместо console.log. Все alert выполняются в правильном порядке. Как показано в примере ниже.

function getCoffee() {
    return new Promise(resolve => {
      setTimeout(() => {resolve("coffee")}, 2000); // it takes 2 seconds to make coffee
    });
  }
  async function go() {
    try {
      alert("ok");
      const coffee = await getCoffee();

      alert(coffee); // ☕

      const wes = await getCoffee();
      alert(wes);

      const wordPromise = getCoffee();
      alert(wordPromise);

      alert("finish");
    } catch (e) {
      console.error(e); // ?
    }
  }
go();
1 голос
/ 15 мая 2019

Проблема в том, что console.log не всегда так синхронно, как можно подумать.Спецификация требует только, чтобы console.log отображало сообщение в консоли разработчика, но не предъявляет никаких требований о том, как и когда сообщение будет отображаться.В зависимости от вашего браузера результаты могут отличаться, однако обычно в нем реализовано что-то вроде следующего:

  • Когда вы делаете вызов на console.log, запрос помещается в стек (поэтому последовательные вызовы на console.log всегда выполняется по порядку)
  • В следующем кадре анимации браузер попытается обработать как можно большую часть стека (минимум один элемент в стеке должен обрабатывается, поэтому браузер может заблокироваться, если вы попытаетесь заблокировать 8 мегабайт данных)
  • «Обработка» стека включает в себя такие вещи, как преобразование ссылок на элементы DOM в ссылки, которые перенесут вас в другое место консоли dev,преобразование объектов JSON в элементы навигации и складные элементы пользовательского интерфейса или замена объектов текстом «[Object object]»
  • После обработки элемента в стеке его необходимо отобразить в консоли.Для этого необходимо отрегулировать высоту консоли, определить, нужна ли вам полоса прокрутки, определить, где текст будет переноситься, и т. Д. Этот процесс (получение того, что вы хотите в консоли и фактически отображение его на экране) называется «рисованием»

Поскольку console.log на самом деле является такой сложной операцией, как эта, она может не завершиться до выполнения оператора alert (в некоторых браузерах).Заменив каждый вызов alert на console.log или каждый вызов console.log на alert, вы должны увидеть, что все выполняется в ожидаемом порядке.

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