【发布时间】:2019-07-17 18:28:36
【问题描述】:
我正在使用生成器函数来模拟可迭代的任务队列:
function* taskQueue() {
for(let i=0; i<10; i++) {
yield new Promise((resolve) => {
setTimeout(() => resolve(i), (11 - i)*1000)
})
}
}
超时应该导致 promise 以相反的顺序解决(假设所有都同时开始),最长在 11 秒内完成。
遍历promise,并使用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() 的情况下 Promise 是同时解决的,而在 awaiting() 的情况下却不是呢?
【问题讨论】:
-
“超时应该导致承诺以相反的顺序解决” 不确定您所说的“相反顺序”是什么意思?预期的结果是什么?
-
超时设置为 11 - i 秒。因此,第一个承诺的超时时间为 11 - 0 = 11 秒,第二个为 10 秒,依此类推,直到第 10 个超时时间为 1 秒。
-
仍然不确定预期的结果是什么?对于第一个示例处代码处的整个程序,总共需要 11 秒才能完成?还是让程序将11 + 10 + 9 + N-1 的总和通过到0 来完成?你想解决什么问题?
-
关键是要创建一组承诺,这些承诺都需要不同的时间才能完成。如果代码以并发方式执行,那么我希望总执行时间接近最长超时时间,就像我使用 Promise.then() 的情况一样。奇怪的是,当等待 promise 时,执行时间反而更长。
-
第一个示例中的代码确实需要 11 秒才能完成。使用
async/await执行awaiting处的代码按顺序执行。这也是预期的结果。使用的模式是一种选择,取决于您要实现的目标。
标签: javascript node.js promise async-await generator