生成器产生的承诺在等待时未同时解决

时间:2019-02-24 01:01:27

标签: javascript node.js promise async-await generator

我正在使用生成器函数来模拟可迭代的任务队列:

function* taskQueue() {
    for(let i=0; i<10; i++) {
        yield new Promise((resolve) => {
            setTimeout(() => resolve(i), (11 - i)*1000)
        })
    }
}

超时应导致承诺以相反的顺序解决(假设所有承诺均在同一时间开始),最长的完成时间为11秒。

遍历承诺,并使用Promise.then(),代码占用长度 最长的超时时间(11秒)完成:

function then() {
    let q = taskQueue();
    for(i of q) {
        i.then(console.log)
    }
}

但是,如果我等待这些承诺,则它们会按顺序解决,并且需要线性时间(66秒)才能完成:

async function awaiting() {
    let q = taskQueue();
    for(i of q) {
        let n = await i;
        console.log(n);
    }
}

这似乎是因为taskQueue在上一个解析之前没有产生下一个诺言,因为如果我将它们推入数组然后等待,则代码将在11秒内执行:

async function awaiting2() {
    let q = taskQueue();
    let tasks = [];
    for(i of q) {
        tasks.push(i);
    }
    for(i of tasks) {
        let n = await i;
        console.log(n);
    }
}

那么为什么在then()的情况下同时解决承诺,而在waiting()的情况下却没有解决呢?

1 个答案:

答案 0 :(得分:3)

这是因为Promises自然是异步的,因为无论Promise处于什么状态(待处理,已解决,错误),程序的其余部分都将继续执行。

通过使用async关键字,您告诉功能块等待用await关键字指定的每个Promise等待该Promise解析,然后再继续执行,这使该功能块同步。 / p>

通过在Promise上调用.then()方法,您将使Promise执行保持异步,但是无论程序中发生了什么,.then()都会在完成时被调用。