Я имею в виду следующий код просто выполняется синхронно:

 someReceiveACallback('event', async () {
   const result = await imAsync() /*1*/
   let anotherResult = null /*2*/
   if (result.authenticated)
     anotherResult = await imAlsoAsync() /*3*/
   send(anotherResult) /*4*/
 })

Поток просто: 1-> 2-> 3-> 4, как будто он синхронный.

Если поведение по умолчанию является асинхронным, зачем отмечать его как {{X 0}}, если оно действительно делает объект синхронным?

-3
Rainning 10 Май 2019 в 15:25

2 ответа

Лучший ответ

Нет, это не значит работать синхронно

async и await являются «синтаксическим сахаром» для Promise. Это означает, что синтаксис эквивалентен следующему в ES2015 и ES2016, где выполняется функция генератора в качестве сопрограммы.

someReceiveACallback('event', coroutine(function*() {
  const result = yield imAsync(); /*1*/
  let anotherResult = null; /*2*/
  if (result.authenticated)
    anotherResult = yield imAlsoAsync(); /*3*/
  send(anotherResult); /*4*/
}));

function coroutine(fn) {
  return function() {
    return new Promise((resolve, reject) => {
      const gen = fn.apply(this, arguments);
      const step = method => result => {
        try {
          var { value, done } = gen[method](result);
        } catch (error) {
          reject(error);
          return;
        }

        if (done) resolve(value);
        else Promise.resolve(value).then(_next, _throw);
      };

      const _next = step('next');
      const _throw = step('throw');

      _next(undefined);
    });
  };
}

Исходный код, созданный babel

Проще говоря, только все до первого встреченного выражения await выполняется синхронно. Это связано с вызовом _next(undefined) в исполнителе конструктора Promise.

После этого функция возвращает обещание вызывающей стороне, которое устанавливается, когда выполнение функции достигает конца своего потока управления.

Каждый блок между последовательно встречающимися await выражениями выполняется внутри собственного асинхронного продолжения .then(...).

Цель сопрограммы - запустить процедуру разрешения обещаний для каждого yield, обнаруженное в генераторе. Когда обещание выполнено, сопрограмма асинхронно повторно входит в поток управления в той же точке, предоставляя разрешенное значение или выбрасывая отклоненную причину. Promise.resolve(value).then(_next, _throw) - это то, что это делает.

Благодаря встроенной поддержке async / await все, что сделано coroutine(), фактически реализовано в цикле событий среды выполнения.

2
Patrick Roberts 23 Авг 2019 в 19:12

Этот код не работает синхронно. Он просто работает по порядку и выглядит синхронно. Если ваша функция использует асинхронные методы, вы можете пометить ее типом «асинхронный».

И «жду», отмечает асинхронную часть

-1
Doğancan Arabacı 10 Май 2019 в 12:37