Javascript 承诺不同步解决,尽管等待
所以我有一个函数,它获取位置并返回一个承诺。我使用mobx作为一个商店,在这里我更新了Javascript 承诺不同步解决,尽管等待,javascript,ecmascript-6,promise,mobx,mobx-react,Javascript,Ecmascript 6,Promise,Mobx,Mobx React,所以我有一个函数,它获取位置并返回一个承诺。我使用mobx作为一个商店,在这里我更新了this.locationStoreProp和this.hotel.subtext属性 public fetchPropertyLocation(some_input_params): Promise<any> { return this.apiSource .fetchPropertyLocationData(input) .then(({ data }) =&g
this.locationStoreProp
和this.hotel.subtext
属性
public fetchPropertyLocation(some_input_params): Promise<any> {
return this.apiSource
.fetchPropertyLocationData(input)
.then(({ data }) => {
runInAction('update from response', () => {
if (data) {
this.locationStoreProp = data.location;
this.hotel.subtext = data.location.score;
}
});
})
.catch(error => {
runInAction('error in location', () => {
//log event
});
return {
error
};
});
}
最后,我简单地等待着他们。我希望fetch
函数promise首先用fetchHotelInfo
promise解析,但我的位置函数promise首先解析,因此我发现属性this.hotel
未定义
public async fetch(options: FetchOptions): Promise<any> {
await fetchClassObj.fetch(params);
await fetchClassObj.fetchPropertyLocation(params);
}
公共异步获取(选项:获取选项):承诺{
等待fetchClassObj.fetch(参数);
等待fetchClassObj.fetchPropertyLocation(参数);
}
这里怎么了?谢谢
另外,请不要担心语法 你这样做怎么样:
public async fetchPropertyLocation(some_input_params): Promise<any> {
try {
let { data } = await this.apiSource.fetchPropertyLocationData(input);
await runInActionPromise('update from response');
this.locationStoreProp = data.location;
this.hotel.subtext = data.location.score;
} catch(error) {
await runInActionPromise('error in location');
//log event
return {error};
}
}
public async fetchHotelInfo(input_params): Promise<any> {
try {
let data = await this.hotelInfoSource.fetch(input);
await runInAction('update hotel from response');
this.hotel = data;
return data;
} catch(error) {
await runInAction('recovering from hotel info call failure');
return {error};
}
}
未经测试
这样你就不必混合使用async/await
和Promises
,而且一切看起来都很整洁。因为承诺
在某种程度上是为了替换回调
而设计的,所以如果您也将运行不活动
函数转换为一个函数,那就太好了
因此:
函数runInAction():Promise{
返回新承诺(…);
}
.catch(()=>runInAction('updateinghotelwithfailure');
作为一个副作用,这将防止链条断裂,并使整个代码看起来更加一致
<强>重要< /强>如果在这样一个链的中间使用回调,它将破坏代码执行的顺序。所以不要在承诺中使用回调(除非回调中包含
resolve()
) 您得到的this.hotel
是未定义的,因为在承诺回调中,您使用另一个非承诺回调调用函数runInAction
。当承诺解析时,runInAction
仍处于挂起状态,尚未执行其回调。为了解决这个问题,我建议创建一个类似以下内容的包装函数:
function runInActionPromise(status) {
return new Promise((res,rej) => {
runInAction(status,res);
});
}
当然,如果runInAction
是您定义的函数,您也可以编辑它以使用承诺而不是回调
此外,您应该在代码中坚持使用async/await
或Promise.then()
,而不是两者兼而有之。我建议async/await
减少/消除代码中似乎猖獗的回调地狱。例如,您可以这样重写fetchPropertyLocation
:
public async fetchPropertyLocation(some_input_params): Promise<any> {
try {
let { data } = await this.apiSource.fetchPropertyLocationData(input);
await runInActionPromise('update from response');
this.locationStoreProp = data.location;
this.hotel.subtext = data.location.score;
} catch(error) {
await runInActionPromise('error in location');
//log event
return {error};
}
}
public async fetchHotelInfo(input_params): Promise<any> {
try {
let data = await this.hotelInfoSource.fetch(input);
await runInAction('update hotel from response');
this.hotel = data;
return data;
} catch(error) {
await runInAction('recovering from hotel info call failure');
return {error};
}
}
这明显更具可读性,您甚至可以将“同步”错误处理与try/catch
一起使用
无论您选择哪种方式,只要您确保在
runInAction
中对回调进行说明,并在您使用它的任何地方使用一个承诺,那么它最终都会起作用。您为什么要将与wait
混合使用呢?只需使用其中一个,我需要更新中的一些变量,然后等待fetchClassObj.fetch(params)。然后(()=>fetchClassObj.fetchPropertyLocation(params))代码>降低5个缩进级别,以这种方式使用承诺,实际上是对承诺意图的嘲弄!使用async/await
并去掉那些丑陋的回调树!还有一个问题是,每次使用runInAction
,您都会将承诺与旧式回调混为一谈,它将承诺的全部点丢到窗口之外,除非你把它封装在<代码>新承诺中,正如你在<代码> FETCH
runInAction
的回调将在稍后某个时候执行,这正是使用承诺的时间-因此您可以捕获该结果并将其与其余异步结果一起显示。更改了answer@Elias你能给我指出一些好的资源来澄清我的观点吗?谢谢。当然,但是如果你知道承诺,没有什么能阻止你。只需开始使用一个API。它使一切更具可读性。如果您有任何问题,请询问更具体的问题。《承诺》总是一本好书。谢谢。但是runInAction
不是我定义的。这是mobx
api方法。另外,你能给我指一些好的资源来澄清我关于这方面的概念吗?谢谢
public async fetchPropertyLocation(some_input_params): Promise<any> {
try {
let { data } = await this.apiSource.fetchPropertyLocationData(input);
await runInActionPromise('update from response');
this.locationStoreProp = data.location;
this.hotel.subtext = data.location.score;
} catch(error) {
await runInActionPromise('error in location');
//log event
return {error};
}
}
public async fetchHotelInfo(input_params): Promise<any> {
try {
let data = await this.hotelInfoSource.fetch(input);
await runInAction('update hotel from response');
this.hotel = data;
return data;
} catch(error) {
await runInAction('recovering from hotel info call failure');
return {error};
}
}