使用 async/await 并发启动

L. *_*ger 6 javascript asynchronous async-await

我以为我对 async await 有很好的理解,直到我尝试了这个:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});

async function asyncTest() {
  console.time();
  const p1 = await promise1;

  if (p1 === 'what') {
    var p2 = await promise2;
  }

  console.log(p1, p2);
  console.timeEnd();
}

asyncTest()
Run Code Online (Sandbox Code Playgroud)

15000 毫秒后,asyncTest正在记录p1& p2。如果取而代之的是promise1promise2转换为返回这些承诺的函数,则执行时间为 25000 毫秒。我不知道是怎么回事。有人能解释一下吗?

Fis*_*ing 4

问题是您的 Promise 回调在您声明它们后立即被调用。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});
Run Code Online (Sandbox Code Playgroud)

至此,两个回调都已被调用。从此时起 10000ms,promise1将解决。从此时起 15000ms,promise2将解决。

async function asyncTest() {
  console.time();
  const p1 = await promise1;

  if (p1 === 'what') {
    var p2 = await promise2;
  }

  console.log(p1, p2);
  console.timeEnd();
}

asyncTest()
Run Code Online (Sandbox Code Playgroud)

此时,由于两个回调都已被调用,因此两者都将在 15000 毫秒内得到解决,正如您所观察到的。

为了将其延长到您期望的 25000 毫秒,请尝试按如下方式重写 Promise:

const promise1 = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve('what'), 10000);
});

const promise2 = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve('?'), 15000);
});
Run Code Online (Sandbox Code Playgroud)

请注意,这些现在是不会立即调用的函数表达式。然后重写你的asyncTest函数来调用这些表达式,而不是简单地等待已经执行的 Promise:

async function asyncTest() {
  console.time();
  const p1 = await promise1();

  if (p1 === 'what') {
    var p2 = await promise2();
  }

  console.log(p1, p2);
  console.timeEnd();
}
Run Code Online (Sandbox Code Playgroud)

这将强制promise2等到promise1完成后再开始执行。