使用 await 关键字之后的区别其实比看上去的还要微妙一些。比如,下面的例子中按顺序调用了 3 个函数,但它们的输出结果顺序是相反的:
async function foo() {
console.log(await Promise.resolve('foo'));
}8
async function bar() {
console.log(await 'bar');
}
async function baz() {
console.log('baz');
}
foo();
bar();
baz();
// baz
// bar
// foo
async/await 中真正起作用的是 await。async 关键字,无论从哪方面来看,都不过是一个标识符。 12 毕竟,异步函数如果不包含 await 关键字,其执行基本上跟普通函数没有什么区别:
async function foo() {
console.log(2);
}
console.log(1);
foo();
console.log(3);
要完全理解 await 关键字,必须知道它并非只是等待一个值可用那么简单。JavaScript 运行时在碰 到 await 关键字时,会记录在哪里暂停执行。等到 await 右边的值可用了,JavaScript 运行时会向消息 队列中推送一个任务,这个任务会恢复异步函数的执行。 因此,即使 await 后面跟着一个立即可用的值,函数的其余部分也会被异步求值。下面的例子演 示了这一点:
async function foo() {
console.log(2);
await null;
console.log(4);
}
console.log(1);
foo();
console.log(3);
// 1
// 2
// 3
// 4
控制台中输出结果的顺序很好地解释了运行时的工作过程: (1) 打印 1; (2) 调用异步函数 foo(); (3)(在 foo()中)打印 2; (4)(在 foo()中)await 关键字暂停执行,为立即可用的值 null 向消息队列中添加一个任务; (5) foo()退出; (6) 打印 3; (7) 同步线程的代码执行完毕; (8) JavaScript 运行时从消息队列中取出任务,恢复异步函数执行; (9)(在 foo()中)恢复执行,await 取得 null 值(这里并没有使用); (10)(在 foo()中)打印 4; (11) foo()返回。 如果 await 后面是一个期约,则问题会稍微复杂一些。此时,为了执行异步函数,实际上会有两个 任务被添加到消息队列并被异步求值。下面的例子虽然看起来很反直觉,但它演示了真正的执行顺序:1
async function foo() {
console.log(2);
console.log(await Promise.resolve(8));
console.log(9);
}
async function bar() {
}
标签:function,foo,console,log,await,js,停止,async,执行
From: https://blog.51cto.com/u_16273048/9346042