Javascript promises - 处理可能的竞争条件

Javascript promises - handle possible race condition

我最近在网上遇到了这个问题,它是解决方案。但是我不完全理解解决方案。

问题:

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
}

在这里,如果我们用名称 X 调用 getResource,并且在执行 load 期间,我们会再次调用同名 X 的函数,它可能会创建另一个名称为 X.

的资源

解决方法是:

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]
}

现在这个解决方案意味着首先,this.resources[name] 将持有一个 Promise 对象,然后一旦承诺被解析,它将持有加载的资源。

我的问题是,如果我们正在等待承诺解决,并且另一个名为 X 的 getResource 调用到达,它将传递 if 语句,并再次调用 new Resource(name) 并等待 load 结束。

但这不会潜在地导致 this.resources[name] 中的第一个 X 资源在第二个 load 完成后被覆盖吗?

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

第二次调用将等到第一次调用完成。两个 javascript 用户函数永远不会并行执行。

这就是第一个版本不起作用的原因 - 函数执行在等待时结束,在继续之前,可能会发生另一个调用。