Await在异步功能上工作正常,但在Promise上却没有

时间:2018-07-02 23:35:20

标签: javascript async-await

我在玩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

有人可以解释第二种情况下的行为吗?谢谢。

5 个答案:

答案 0 :(得分:1)

构造Promise时,该Promise的主体将立即执行。这就是为什么在第二段代码中,console.lognew 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承诺都被依次执行(至完成) 。

在第一种情况下,asyncrun函数,其对async的2个await调用是顺序执行的。

在第二种情况下,testtest函数,并且它的单个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()

希望这种解释有所帮助!