Search code examples
javascriptes6-promise

Javascript promises - handle possible race condition


I've recently encountered this question online and it's solution. Yet I do not fully understand the solution.

The question:

this.resources = {};

async function getResource (name) {

    if (this.resources[name]) {
        return this.resources[name]
    }

    const resource = new Resource(name)
    
    await resource.load()

    this.resources[name] = resource

    return resource
}

Here, in case we have a call to getResource with name X and during the time load is executed, we get another call to the function with the same name X it might create another resource with name X.

The solution to this is:

this.resources = {};

async function getResource (name) {

    if (this.resources[name]) {
        return this.resources[name]
    }

    const resource = new Resource(name)

    this.resources[name] = resource.load().then(()=>resource)

    return this.resource[name]
}

Now this solution means that first, this.resources[name] will hold a Promise object and then once the promise is resolved, it will hold the loaded resource.

My question is, in case we are waiting for the promise to resolve, and another call to getResource with name X arrives, it will pass the if statement, and once again call new Resource(name) and wait for load to end.

But won't that cause potentially, to have the first X resource in this.resources[name] to be over-riden once the second load completes?


Solution

  • another call to getResource with name X arrives, it will pass the if statement

    Second call will wait till the first completes. Two javascript user functions are never executed in parallel.

    That's why the first version doesn't work - the function execution ends on the await and before it continues, another call can occur.