Search code examples
javascriptasync-awaites6-promise

Var has same value after using await in function running using Promise.all


In a function run1 random value is generated & stored in random_var, await is used to delay and then random_value is resolved.

When running run1 asynchronously using Promise.all the random_var is changed when logging after await statement as shown in the code snippet demo

main()

async function main() {
    await Promise.all([run1(), run1(), run1()]).then(value => {
        console.log({ values: value })
    })
}

async function run1() {
    return new Promise(async (resolve, reject) => {
        random_var = makeid(6)
        console.log('Logging 1st time has different values', random_var)
        await new Promise(resolve => setTimeout(resolve, 500))
        console.log('Logging 2nd time has same values', random_var)
        resolve(random_var)
    })
}


function makeid(length) {
    var result = '';
    var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var charactersLength = characters.length;
    for (var i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
}


Solution

  • This has to do with hoisting and scope. You line random_var = makeid(6) doesn't use let or const so it gets hoisted to the global scope where it will not change when the promises resolve. changing it to const random_var = makeid(6) (or let or var, but best practice is const here because you're not going to ever mutate it) should resolve the issue.

    main()
    
    async function main() {
        await Promise.all([run1(), run1(), run1()]).then(value => {
            console.log({ values: value })
        })
    }
    
    async function run1() {
        return new Promise(async (resolve, reject) => {
            const random_var = makeid(6)
            console.log('Logging 1st time has different values', random_var)
            await new Promise(resolve => setTimeout(resolve, 500))
            console.log('Logging 2nd time has same values', random_var)
            resolve(random_var)
        })
    }
    
    
    function makeid(length) {
        var result = '';
        var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        var charactersLength = characters.length;
        for (var i = 0; i < length; i++) {
            result += characters.charAt(Math.floor(Math.random() * charactersLength));
        }
        return result;
    }