iep*_*ure 3 javascript recursion node.js async-await setimmediate
我一直在阅读有关如何不阻止 Node 的事件循环的内容。避免阻塞的一种方法是使用分区。
我试图在我的代码中使用分区循环,但我似乎无法等待我的循环。这是我的代码的简化版本:
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);
Run Code Online (Sandbox Code Playgroud)
这会返回“Report is { someValue: 1 }”,但我希望 someValue 为 1000。
我猜 setImmediate 不会返回承诺,所以我尝试承诺它:
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);
Run Code Online (Sandbox Code Playgroud)
但这也会返回“Report is { someValue: 1 }”。
那么,我如何等待这个递归 setImmediate“循环”,以便我 console.log 仅在整个递归周期完成后才报告?
当你已经 promisified 时setImmediate,你不再向它传递回调。相反,您只需await它返回的承诺即可。然后你会进行递归调用:
async function runLoop() {\n \xe2\x80\xa6\n if (\xe2\x80\xa6) {\n await setImmediatePromise();\n return runLoop();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但是,async/await使您能够编写实际的循环:
const setImmediatePromise = util.promisify(setImmediate);\n\nconst report = {\n someValue: 0\n};\n\nwhile (report.someValue < 1000) {\n report.someValue += 1;\n // all sorts of synchronous operations here\n await setImmediatePromise();\n}\n\nconsole.log(\'Report is\', report);\nRun Code Online (Sandbox Code Playgroud)\n\n(请注意与递归的细微差别:在第一次迭代之前已经检查了条件,并且setImmediate在最后一次迭代之后再次运行。如果需要,请使用do/while甚至while(true)+ if(\xe2\x80\xa6)break;。)
顺便说一句,如果您已经在循环内执行异步(非阻塞)操作,则没有理由setImmediate向其添加额外的操作。该指南仅处理会阻塞事件循环的复杂同步计算。