简体   繁体   中英

How to promisify and await for setImmediate in Node?

I've been reading about how to not block Node's event loop. One way to avoid blocking is to use partitioning .

I'm trying to use a partitioned loop in my code, but I cannot seem to await for my loop. Here's a simplified version of my code:

    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);

This returns "Report is { someValue: 1 }", but I'd want someValue to be 1000.

I'm guessing setImmediate doesn't return a promise, so I've tried promisifying it:

    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);

But this also returns "Report is { someValue: 1 }".

So, how can I await for this recursive setImmediate "loop" so that I console.log report only after the entire recursion cycle is finished?

When you have promisified setImmediate , you no longer pass a callback to it. Instead, you just await the promise it returns. Then afterwards you'd do the recursive call:

async function runLoop() {
    …
    if (…) {
        await setImmediatePromise();
        return runLoop();
    }
}

However, async / await gives you the capability to just write an actual loop:

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);

(Notice the slight difference to the recursion: the condition is already checked before the first iteration, and the setImmediate runs once more after the last iteration. Use do / while or even while(true) + if(…)break; if necessary.)

Btw, if you are already doing asynchronous (non-blocking) operations inside the loop, there is no reason to add an extra setImmediate to it. The guide only deals with complex synchronous calculations that would block the event loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM