Почему методы «async» машинописи действуют как синхронизация до первого появления «await» - PullRequest
2 голосов
/ 12 мая 2019

Почему код выполняется в том же «стеке» только перед первым ожиданием?

 class SomeSyncClass {

  async method(): Promise<void> { 
     console.log('in start async');

     await this.someotherMethod();

    console.log('in finish async');
  }

  someotherMethod(): void { }


  method2(): void {
    console.log('before');
    this.method();
    console.log('after');
  }
}

new SomeSyncClass().method2(); 

выход:

before 
in start async
after
in finish async

Но если я уберу await - он будет выполняться синхронно:

 class SomeSyncClass {

  async method(): Promise<void> { 
     console.log('in start async');

     this.someotherMethod();

    console.log('in finish async');
  }

  someotherMethod(): void { }


 method2(): void {
   console.log('before');
   this.method();
   console.log('after');
}
}

new SomeSyncClass().method2(); 

выход: * +1010 *

before
in start async
in finish async
after

Ответы [ 2 ]

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

То, что вы испытываете, происходит как в JavaScript, так и в TypeScript. Помещение await перед выражением, которое не является Обещанием , превращает выражение в разрешенное Обещание.

Если значение выражения после оператора await не является Обещанием, оно преобразуется в разрешенное Обещание.

Ванильный JavaScript с использованием async/await:

Следующий фрагмент эквивалентен вашему исходному примеру await. Ожидание заставляет синхронный func3() вести себя так, как если бы он был асинхронным, потому что он был преобразован в разрешенный Promise.

const func3 = () => {}

const func2 = async() => {
  console.log('in start async');
  // The await wraps the synchronous func3 in a resolved Promise.
  await func3();
  console.log('in finish async');
}

const func1 = () => {
  console.log('before');
  func2();
  console.log('after');
}

func1();

Эквивалентный JavaScript с использованием Promise:

Этот следующий фрагмент показывает, что происходит более подробно. Я удалил await и вручную обернул func3() в разрешенное Promise. Это может прояснить, что происходит.

const func3 = () => {}

const func2 = () => {
  console.log('in start async');

  // This is the equivalent of await func3(); console.log('...');
  Promise.resolve(func3()).then(() => {
    console.log('in finish async');
  });
}

const func1 = () => {
  console.log('before');
  func2();
  console.log('after');
}

func1();
1 голос
/ 12 мая 2019

Это ожидаемое поведение программирования в асинхронном стиле.

В этом методе:

async method(): Promise<void> { 
  console.log('in start async');
  await this.someotherMethod();
  console.log('in finish async');
}

Второй оператор журнала не может быть выполнен в том же тике, что и первый, из-заожидание вызова в середине.По сути, он компилируется примерно так:

async method(): Promise<void> { 
  console.log('in start async');
  this.someotherMethod().then(result => {
    console.log('in finish async');    
  })
}

, который, как вы можете видеть, вызывает второй оператор журнала только после разрешения someotherMethod.

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

Эти правила не имеют ничего общего с Typescript и напрямую связаны со средой выполнения JavaScript и спецификацией ECMA.

...