我在玩async / await,发现行为上有些奇怪的差异,具体取决于调用await的位置。
function test(msg) {
return new Promise(accept => {
console.log('in promise ', msg);
setTimeout(() => {
console.log('in timeout ', msg);
accept();
}, 1000)
});
}
async function run() {
await test('a');
await test('b');
}
run();
它输出
in promise a
in timeout a
in promise B
in timeout B
,这是预期的。但是,如果我在“测试”函数中移动等待,那么结果将以非常意外的方式更改:
async function test(msg) {
const promise = new Promise(accept => {
console.log('in promise ', msg);
setTimeout(() => {
console.log('in timeout ', msg);
accept();
}, 1000)
});
await promise;
}
function run() {
test('a');
test('B');
}
run();
输出
in promise a
in promise B
in timeout a
in timeout B
有人可以解释第二种情况下的行为吗?谢谢。
答案 0 :(得分:1)
构造Promise时,该Promise的主体将立即执行。这就是为什么在第二段代码中,console.log
内new Promise
内的setTimeout
立即出现的原因。
那么为什么在第一个示例中它没有做同样的事情?这是因为直到第一次完成,才调用第二次test
。这两个Promises本质上是链接在一起的,就像您写的是这样:
return test('a').then(() => test('B'));
如果您这样做:
const promiseA = test('a');
const promiseB = test('B');
await Promise.all([promiseA, promiseB]);
...您将获得与第二个代码块相同的结果。
答案 1 :(得分:1)
private
函数内的所有await
承诺都被依次执行(至完成) 。
在第一种情况下,async
是run
函数,其对async
的2个await
调用是顺序执行的。
在第二种情况下,test
是test
函数,并且它的单个async
操作完全无效(因为await
函数没有第二个{{1 }}操作,需要“等待”。
答案 2 :(得分:0)
这两个代码块是相同的:
等待中
await test('a');
test('B');
具有链接
test('a')
.then(() => {
test('B');
});
您对await
所做的所有工作正在等待,以期继续前进。 async
/ await
只是语法糖,可以避免所有带有多个promise的嵌套
答案 3 :(得分:0)
您的run
函数不是异步的,因此它仅运行两个函数。 async
/ await
只是Promise的另一种语法,因此您的第二个示例与此等效:
function test(msg) {
const promise = new Promise(accept => {
console.log('in promise ', msg);
setTimeout(() => {
console.log('in timeout ', msg);
accept();
}, 1000)
});
return promise.then(() => undefined);
}
function run() {
test('a');
test('B');
}
run();
答案 4 :(得分:0)
要清楚地了解会发生什么,您需要在代码末尾(在console.log('end')
之后)放置另一个run();
:
in promise a
end
in timeout a
in promise b
in timeout b
in promise a
in promise B
end
in timeout a
in timeout B
await
暂停执行当前功能,直到承诺被解决为止。
在第一个示例中,执行test('a')
,然后暂停run()
,直到test('a')
返回的承诺解决,导致console.log('end')
被执行。
在第二个示例中,test('a')
会部分执行,但是会暂停,直到兑现承诺,因此接下来执行test('b')
,也会暂停,但是然后{ {1}}完成,因此可以执行run()
。
希望这种解释有所帮助!