我正在使用生成器函数来模拟可迭代的任务队列:
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()的情况下却没有解决呢?
答案 0 :(得分:3)
这是因为Promises
自然是异步的,因为无论Promise处于什么状态(待处理,已解决,错误),程序的其余部分都将继续执行。
通过使用async
关键字,您告诉功能块等待用await
关键字指定的每个Promise等待该Promise解析,然后再继续执行,这使该功能块同步。 / p>
通过在Promise上调用.then()
方法,您将使Promise执行保持异步,但是无论程序中发生了什么,.then()
都会在完成时被调用。