async/await 如何串行和并行工作?

How is async/await working in serial and parallel?

我有两个 async 函数。他们都在等待两个 3 秒的函数调用。但是第二个比第一个快。我认为更快的是 运行 并行和其他串行。我的假设正确吗?如果是,为什么会发生这种情况,因为这两个函数在逻辑上看起来是一样的?

function sleep() {
  return new Promise(resolve => {
    setTimeout(resolve, 3000);
  });
}

async function serial() {
  await sleep();
  await sleep();
}

async function parallel() {
  var a = sleep();
  var b = sleep();
  await a;
  await b;
}

serial().then(() => {
  console.log("6 seconds over");
});

parallel().then(() => {
  console.log("3 seconds over");
});

如果你这样写你的 serial 函数会更清楚:

async function serial() {
  var a = sleep(); //
  await a;         // await sleep();

  var b = sleep(); //
  await b;         // await sleep();
}

async function parallel() {
  var a = sleep();
  var b = sleep();
  await a;
  await b;
}

这里可以清楚的看到,在serial函数中,第二个sleep()是在第一个sleep()完成后才调用的,而在parallel中是调用立即,在第一个完成之前,然后等待两个完成。因此,虽然它们可能看起来在功能上相同,但它们有细微的不同。

因为sleep()函数是一个同步函数,它只是return一个异步promise,例如:

function sleep (time) {
    return new Promise((resolve) => setTimeout(resolve, time));
}

parallel()中,两个sleep()同步初始化两个promise,同时等待resolved,大约需要3s。

但是,在serial()中,两个await sleep()意味着第二个sleep() promise必须等待第一个sleep()被解决,所以它会是大约6s。

Frxstream 已经有 。在此基础上,提供一些观点:

首先要认识到的是创建了 Promise "hot" - 也就是说,当您拥有一个 Promise 对象时,它已经 "in progress".

第二个重要的概念是 await 就像一个 "asynchronous wait" - 也就是说,它会暂停函数的执行,直到该承诺完成。

因此,serial 函数调用 sleep,返回承诺,然后(异步)等待该承诺完成。在该承诺 3 秒后完成后,serial 再次调用 sleep,得到一个承诺,然后(异步)等待该承诺完成。 3 秒后该承诺完成后,serial 完成。

parallel 函数调用 sleep 并将其 promise 存储在 a,然后调用 sleep 并将其 promise 存储在 b,然后(异步)等待 a 完成。 a 3 秒后完成后,parallel(异步)等待 b 完成。 b 几乎立即完成后,parallel 完成。

连载运行:运行函数一个接一个

//  It’s slow! and use only for serial(one after another) run
async function doThings() {
    const thing1 = await asyncThing1(); // waits until resolved/rejected
    console.log(thing1);

    const thing2 = await asyncThing2(); // starts only after asyncThing1() has finished.
    console.log(thing2);
}

doThings();

并行运行: 运行函数并行

// ✅ async code is run in parallel!
async function doThings() {
    const p1 = asyncThing1(); // runs parallel
    const p2 = asyncThing2(); // runs parallel


    // Method 1: Prefer => Promise.all()
    const [resultThing1, resultThing2] = await Promise.all([p1, p2]); // waits for all 
    // the promises get resolved or fails fast (If one of the promises supplied to it 
    // rejects, then the entire thing rejects).

    // Method 2: Not-Preferred
    const resultThing1 = await p1;
    const resultThing2 = await p2;

    console.log(resultThing1); // reaches here only after both the p1 & p2 have completed.
    console.log(resultThing2);
}

doThings();