并行vs系列-如何使用异步顺序执行功能

时间:2019-08-15 18:28:20

标签: javascript asynchronous async-await

根据google docs对Async的解释,以下名为“ parallel”的函数应并行执行,而名为“ series”的函数应按顺序执行。
Async Functions Explanation on Google Developers

并行操作需要2秒钟才能完成。
系列需要4秒。
但是,它们都在2秒内完成。

为什么series()总共不花4秒?我希望第一个计时器在2秒后完成,然后第二个计时器在另外2秒后完成?

async function series() {
    function timer(time) { setTimeout(function(){ console.log(`Hello ${time}`) }, time); }

    await timer(2000);  // Wait 2 seconds…
    await timer(2000);  // …should wait another 2 seconds
}
series()  // should take 4 seconds to complete, but only takes 2 seconds

为什么这可以并行工作,但是串联却不能连续工作?

async function parallel() {
    function timer(time) { setTimeout(function(){ console.log(`Hello ${time}`) }, time); }

    let one = timer(2000);  // Start a 2 second timer asynchronously…
    let two = timer(2000);  // …meaning this timer happens in parallel. 
    await one;  // Wait 2 seconds for the first timer
    await two;  // …by which time this time finishes around same time
}
parallel()  // completes in 2 seconds

5 个答案:

答案 0 :(得分:2)

await运算符用于等待Promise。如果您让计时器函数返回一个承诺,该承诺将在调用超时回调时解决,那么它将按预期工作。

您可以在此处了解更多信息:Promise await

答案 1 :(得分:1)

setTimeout不返回可以等待的承诺。因此,它不会等待setTimeout完成。因此,setTimeout函数将添加到队列中,并在2秒内立即执行。

如果添加承诺,第二个计时器将在4秒后执行

答案 2 :(得分:0)

您需要返回Promise并稍后解决

function delay(t, v) { return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); }

这里是解释:  using setTimeout on promise chain

答案 3 :(得分:0)

因为在您的情况下,您先执行setTimeout,该命令立即执行,然后执行下一个setTimeout

这两个计时器都将在2秒内执行。

Promise为例,将获得预期的结果

答案 4 :(得分:0)

在两个示例中,您都应该返回promise来检查代码片段的并行性和串行性。

在您当前的示例中,await仅等到函数执行完毕(在您的情况下),因为setTimeout立即返回以便理解该示例,请使用Promise来查看将来返回的值。

function timer(time) { 
    return new Promise((resolve, reject) => setTimeout(() => resolve(Math.random()), time), null);
 }
async function series() {
    await timer(2000);  // Wait 2 seconds…
    await timer(2000);  // …should wait another 2 seconds
}
series()  // should take 4 seconds to complete, but only takes 2 seconds

在并行执行的情况下

function timer(time) { 
    return new Promise((resolve, reject) => setTimeout(() => resolve(Date.now()), time), null);
 }
async function parallel() {
    let d1 = timer(2000);
    let d2 = timer(2000);
    // here both the functions are invoked and after invoking them we are waiting
    await d1;
    await d2;
}
parallel()