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 用户函数永远不会并行执行。
这就是第一个版本不起作用的原因 - 函数执行在等待时结束,在继续之前,可能会发生另一个调用。
我最近在网上遇到了这个问题,它是解决方案。但是我不完全理解解决方案。
问题:
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 用户函数永远不会并行执行。
这就是第一个版本不起作用的原因 - 函数执行在等待时结束,在继续之前,可能会发生另一个调用。