为什么打字稿 'async' 方法在第一次 'await' 出现之前就像同步一样
Why typescript 'async' methods act like a sync till the first 'await' occurrence
为什么代码在同一个 'stack' 中只在第一次等待之前执行?
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();
输出:
before
in start async
in finish async
after
这是 async-await 风格编程的预期行为。
在这个方法中:
async method(): Promise<void> {
console.log('in start async');
await this.someotherMethod();
console.log('in finish async');
}
由于中间的 await 调用,第二个日志语句无法在与第一个相同的时间间隔内执行。它基本上被编译成这样的东西:
async method(): Promise<void> {
console.log('in start async');
this.someotherMethod().then(result => {
console.log('in finish async');
})
}
如您所见,仅在 someotherMethod
解析后才调用第二个日志语句。
然而,由于 async-await 规则,第二个变体根本没有被转换。事件尽管 someotherMethod
returns 是一个承诺,但该承诺会被忽略并超出范围。
这些规则与 Typescript 无关,直接融入 JavaScript 运行时和 ECMA 规范。
您遇到的情况在 JavaScript 和 TypeScript 中都会发生。在不是 Promise turns the expression into a resolved Promise.
的表达式之前放置 await
If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise.
原版 JavaScript 使用 async/await
:
以下代码段等同于您原来的 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();
为什么代码在同一个 'stack' 中只在第一次等待之前执行?
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();
输出:
before
in start async
in finish async
after
这是 async-await 风格编程的预期行为。
在这个方法中:
async method(): Promise<void> {
console.log('in start async');
await this.someotherMethod();
console.log('in finish async');
}
由于中间的 await 调用,第二个日志语句无法在与第一个相同的时间间隔内执行。它基本上被编译成这样的东西:
async method(): Promise<void> {
console.log('in start async');
this.someotherMethod().then(result => {
console.log('in finish async');
})
}
如您所见,仅在 someotherMethod
解析后才调用第二个日志语句。
然而,由于 async-await 规则,第二个变体根本没有被转换。事件尽管 someotherMethod
returns 是一个承诺,但该承诺会被忽略并超出范围。
这些规则与 Typescript 无关,直接融入 JavaScript 运行时和 ECMA 规范。
您遇到的情况在 JavaScript 和 TypeScript 中都会发生。在不是 Promise turns the expression into a resolved Promise.
的表达式之前放置await
If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise.
原版 JavaScript 使用 async/await
:
以下代码段等同于您原来的 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();