Разве это не вводит в заблуждение асинхронный, когда это на самом деле означает работать синхронно? - PullRequest
0 голосов

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

 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, как если бы он был синхронным.

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

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

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

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

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

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(), фактически реализовано в цикле событий среды выполнения.

0 голосов
/ 10 мая 2019

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

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

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