如何在Promise.all的then回调中正确使用二次await?
问题解决方法
报错的核心原因是:.then()的回调函数没有声明为async,导致内部无法使用await语法。同时你的代码还存在一个问题:Promise.all()后续逻辑的返回值没有被外层函数接收,最终retrieveServiceRequest这个thunk可能无法返回正确的数据。
这里提供两种修复方案:
方案一:给then回调添加async声明
直接修改.then的回调函数,加上async关键字,同时确保把整个Promise链的返回值return出去:
export const retrieveServiceRequest = createAsyncThunk( 'csm/retrieveServiceRequest', async (retrievalPayload: any) => { try { if (retrievalPayload.userId && retrievalPayload.serviceRequestTag) { const userServiceRequestKey: string = retrievalPayload.userId + '_' + retrievalPayload.serviceRequestTag; // 返回整个Promise链的结果 return await Promise.all([ csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_EDITED, userServiceRequestKey), csmIndexedDbService.getCSMData(CSM_Stores.CSM_SR_UNEDITED, userServiceRequestKey) ]) .then(async (requestDataArray) => { // 给回调添加async声明 if (requestDataArray.length > 0 && requestDataArray[0]){ return { serviceRequest: requestDataArray[0], serviceRequestOriginal: requestDataArray[1], isDirty: true, addToStore: true } } else { // 此时await可正常使用 return await csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId); } }) .catch(error => { console.log(error); // 抛出错误让redux-thunk处理失败状态 throw error; }); } } catch (error) { console.log('Error: ', error); throw error; } } );
方案二:用async/await完全替代then链(更推荐)
既然外层已经是async函数,直接用await处理Promise.all,代码逻辑更清晰,避免回调嵌套:
export const retrieveServiceRequest = createAsyncThunk( 'csm/retrieveServiceRequest', async (retrievalPayload: any) => { try { if (retrievalPayload.userId && retrievalPayload.serviceRequestTag) { const userServiceRequestKey: string = retrievalPayload.userId + '_' + retrievalPayload.serviceRequestTag; try { 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 } } } catch (dbError) { console.log('IndexedDB加载失败:', dbError); } // DB加载失败或无数据时,调用API获取 return await csmRequestDataService.getServiceRequest(retrievalPayload.serviceRequestId); } } catch (error) { console.log('Error: ', error); throw error; } } );
这种写法把IndexedDB的操作单独用try/catch包裹,失败后直接执行API调用,逻辑更直观,也避免了then链的嵌套问题。
内容的提问来源于stack exchange,提问作者Hank
相关产品推荐
相关产品推荐

