Search code examples
javascriptasynchronouspromisesynchronizationglobal-variables

Updating a common global data-structure using multiple promises in Javascript


Consider the following code:

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

var globalList = Array();
globalList[0] = "Test";
globalList[1] = "Another Test";

async function coreFunc(promiseName, sleepTime) {
    console.log("Started CoreFunc: "+promiseName);

    var localList = globalList;

    console.log("Length of local array: "+localList.length);
    console.log("Length of global array: "+globalList.length);

    if (promiseName != "Promise0") {
        for (i = 0; i < localList.length; i++) {
            console.log(localList[i]);
        }
    }

    if (promiseName == "Promise0") {
        var testList = new Array();
        testList[0] = "Changed";
        globalList = testList;
    }
    await sleep(sleepTime);

    console.log("Length of local array: "+localList.length);
    console.log("Length of global array: "+globalList.length);

    console.log("Done with CoreFunc: "+promiseName);
}

async function testMultiplePromises() {
    var thArray = Array();

    for (i = 0; i < 4; i++) {
        var pr = new Promise(resolve => coreFunc("Promise" + i, 3000));
        thArray[i] = pr;
    }

    for (i = 0; i < thArray.length; i++) {
        await thArray[i];
    }
}

globalList is an array that is global. When the above code is invoked like the following:

await testMultiplePromises();

The code goes into an infinite loop. The problem is definitely in the following segment where I am reinitializing the global variable to some different array:

    if (promiseName == "Promise0") {
        var testList = new Array();
        testList[0] = "Changed";
        globalList = testList;
    }

Is there a way to copy the global datastructure to a local variable without leading to index out of bounds or infinite loop kind of issues? The following code is definitely not doing the job:

var localList = globalList;

What should be done in order to ensure that the Promises either get the older array or get the newer array? To rephrase, how do I make sure the code inside coreFunc (Promise0) that changes the global data structure is protected?


Solution

    1. Infinite loop is caused by global i variable on for loops. You should type it like this
    ...
    for (var i = 0; i < localList.length; i++) {
    ...
    for (var i = 0; i < 4; i++) {
    ...
    for (var i = 0; i < thArray.length; i++) {
    ...
    
    1. To "protect" array you can just copy it like this
    var localList = JSON.parse(JSON.stringify(globalList));