Han*_*ank 0 javascript promise async-await reactjs
我有两个调用来解析从 indexeddb 检索数据的承诺,如果无法加载数据,我希望它从 API 检索数据。
export const retrieveServiceRequest = createAsyncThunk(
'csm/retrieveServiceRequest',
async (
retrievalPayload: any
) => {
try {
if (retrievalPayload.userId && retrievalPayload.serviceRequestTag) {
const userServiceRequestKey: string = retrievalPayload.userId + '_' + retrievalPayload.serviceRequestTag;
await Promise.all([
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_EDITED, userServiceRequestKey),
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_UNEDITED, userServiceRequestKey)
])
.then (requestDataArray => {
if (requestDataArray.length > 0 && requestDataArray[0]){
return { serviceRequest: requestDataArray[0], serviceRequestOriginal: requestDataArray[1], isDirty: true, addToStore: true }
} else {
return await csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId);
}
})
.catch (error =>
console.log(error)
);
}
} catch (error) {
console.log('Error: ', error);
}
}
);
Run Code Online (Sandbox Code Playgroud)
我不确定的部分是:
return await csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId);
Run Code Online (Sandbox Code Playgroud)
等待 API 时出现错误:
“await”表达式仅允许在异步函数内和模块的顶层使用
我应该如何处理第二轮的等待?
您可以使then处理程序异步,但最好不要混合两种样式。将 ed 表达式的结果分配await给一个变量,然后直接使用它,而不需要处理程序then。
export const retrieveServiceRequest = createAsyncThunk(
'csm/retrieveServiceRequest',
async (
retrievalPayload: any
) => {
try {
if (retrievalPayload.userId && retrievalPayload.serviceRequestTag) {
const userServiceRequestKey: string = retrievalPayload.userId + '_' + retrievalPayload.serviceRequestTag;
// assign to variable .
const requestDataArray = await Promise.all([
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_EDITED, userServiceRequestKey),
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_UNEDITED, userServiceRequestKey)
])
// move out of .then handler
if (requestDataArray.length > 0 && requestDataArray[0]){
return { serviceRequest: requestDataArray[0], serviceRequestOriginal: requestDataArray[1], isDirty: true, addToStore: true }
} else {
return await csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId);
}
}
} catch (error) {
console.log('Error: ', error);
}
}
);
Run Code Online (Sandbox Code Playgroud)
不要用try..catch和吞掉错误console.error,只需让它们冒出来 -
export const retrieveServiceRequest = createAsyncThunk(
'csm/retrieveServiceRequest',
async (
retrievalPayload: any
) => {
if (retrievalPayload.userId && retrievalPayload.serviceRequestTag) {
const userServiceRequestKey: string = retrievalPayload.userId + '_' + retrievalPayload.serviceRequestTag;
const requestDataArray = await Promise.all([
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_EDITED, userServiceRequestKey),
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_UNEDITED, userServiceRequestKey)
])
if (requestDataArray.length > 0 && requestDataArray[0]){
return { serviceRequest: requestDataArray[0], serviceRequestOriginal: requestDataArray[1], isDirty: true, addToStore: true }
} else {
return await csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId);
}
}
}
);
Run Code Online (Sandbox Code Playgroud)
呼叫者可以随心所欲地处理它们 -
retrieveServiceRequest.catch(console.error)
Run Code Online (Sandbox Code Playgroud)
最后避免return-await ...反模式。所有async函数都隐式返回一个承诺 -
export const retrieveServiceRequest = createAsyncThunk(
'csm/retrieveServiceRequest',
async (
retrievalPayload: any
) => {
if (retrievalPayload.userId && retrievalPayload.serviceRequestTag) {
const userServiceRequestKey: string = retrievalPayload.userId + '_' + retrievalPayload.serviceRequestTag;
const requestDataArray = await Promise.all([
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_EDITED, userServiceRequestKey),
csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_UNEDITED, userServiceRequestKey)
])
if (requestDataArray.length > 0 && requestDataArray[0]){
return { serviceRequest: requestDataArray[0], serviceRequestOriginal: requestDataArray[1], isDirty: true, addToStore: true }
} else {
// this does the exact same thing
return csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId);
}
}
}
);
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助您了解该图案的优雅和简洁async..await。如果正确使用,它允许编写者在同步和异步控制流之间无缝且轻松地转换。