我一直在阅读有关如何不阻止Node的事件循环的信息。避免阻塞的一种方法是使用partitioning。
我正在尝试在代码中使用分区循环,但是似乎无法等待循环。这是我的代码的简化版本:
const report = {
someValue: 0
};
const runLoop = async () => {
report.someValue += 1;
// all sorts of async operations here that use async-await
if (report.someValue < 1000) {
await setImmediate(runLoop);
}
};
await runLoop();
console.log('Report is', report);
这将返回“Report is {someValue:1}”,但我希望someValue为1000。
我猜setImmediate不会返回 promise ,所以我尝试了使它成问题:
const setImmediatePromise = util.promisify(setImmediate);
const report = {
someValue: 0
};
const runLoop = async () => {
report.someValue += 1;
// all sorts of async operations here that use async-await
if (report.someValue < 1000) {
await setImmediatePromise(runLoop);
}
};
await runLoop();
console.log('Report is', report);
但这还会返回“Report is {someValue:1}”。
因此,如何等待此递归setImmediate“循环”,以便仅在整个递归循环完成后才对console.log报告?
最佳答案
promise 了setImmediate
后,您将不再向其传递回调。相反,您只需await
它返回的 promise 。然后,您将进行递归调用:
async function runLoop() {
…
if (…) {
await setImmediatePromise();
return runLoop();
}
}
但是,
async
/await
使您能够编写实际的循环:const setImmediatePromise = util.promisify(setImmediate);
const report = {
someValue: 0
};
while (report.someValue < 1000) {
report.someValue += 1;
// all sorts of synchronous operations here
await setImmediatePromise();
}
console.log('Report is', report);
(请注意,递归略有不同:在第一次迭代之前已经检查了条件,并且
setImmediate
在最后一次迭代之后再次运行。如有必要,请使用do
/while
甚至while(true)
+ if(…)break;
。)顺便说一句,如果您已经在循环内执行了异步(非阻塞)操作,则没有理由向其添加额外的
setImmediate
。 guide仅处理会阻塞事件循环的复杂同步计算。