Ad

Unexpected Behavior - Async Await When Required With IIFE?

- 1 answer

I've two nodejs files, in which async-await doesn't work, if I require a node module (test2.js) which has IIFE defined in it.

test1.js

async function abc() {
    console.log(1)
    let computeFunction = await require("./test2");
    console.log(4)
    computeFunction()
    return null;
}

(async () => { await abc() })()

test2.js

The idea here is to export a function which does some computations,
but before exporting, I need to initialize database connections so that the computation function will work properly.

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

(async () => {
    console.log(2)
    // some connection initialization
    await sleep(1000)
    console.log(3)
    return null;
})()

module.exports = async () => {
    // does some computation with those connections
    console.log(5)
    return null;
}

Output

Actual

1
2
4
5
3

Expected

1
2
3
4
5

I figured other solution by not using IIFE, but I want to know why async-await won't work when requiring a module which has an IIFE

Ad

Answer

It's a very wrong statement async-await won't work when requiring a module which has an IIFE. Actual output is different from the expected output because of synchronous nature of require not because of IIFE.

You can get output in the order of 1,2,3(after waiting for 1000ms), 4 ,5 if you use any asynchronous require function.

Check this:-

test1.js

const asyncRequire = require('./async-require');

async function abc() {
    console.log(1)
    let computeFunction = await asyncRequire("./test2.js");
    console.log(4)
    computeFunction()
    return null;
}

(async () => { await abc() })();

test2.js

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

await (async () => {
    console.log(2)
    // some connection initialization
    await sleep(1000)
    console.log(3)
    return null;
})();

module.exports = async () => {
    // does some computation with those connections
    console.log(5)
    return null;
}

async-require.js

const fs = require('fs');
module.exports = async path=>{
    return new Promise((success, fail)=>{
        fs.readFile(path, async (error, file)=>{
            const myModule = {};
            await eval(`(async (module)=>{ ${file.toString()} })(myModule);`);
            success(myModule.exports);
        }); 
    })
}
Ad
source: stackoverflow.com
Ad