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

时间:2017-08-03 08:52:07

标签: javascript async-await ecmascript-2017

我有两个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");
});

3 个答案:

答案 0 :(得分:7)

如果你像这样编写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中则立即调用,在第一个完成之前,然后它等待两个完成。因此,虽然他们可能看起来在功能上相同,但它们却略有不同。

答案 1 :(得分:6)

Frxstream已经有an excellent answer。以此为基础,并提供一些观点:

首先要认识到的是,Promise已经被创造出来了#34; hot" - 也就是说,当你有一个承诺对象时,它已经在进行中了#34;。

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

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

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

答案 2 :(得分:3)

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

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

parallel()中,两个sleep()同步初始化两个承诺,他们等待同时解决,它将是大约3秒。

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