使用Promise.all调用多API并dispatch时返回undefined问题排查
排查API调用后Dispatch返回Undefined的问题
我帮你梳理下代码里的几个关键问题,这就是你拿到undefined的核心原因:
问题1:Promise.all接收的不是Promise实例
你在代码里写了apis.map(api => api(http, profileId)),这里确实调用API拿到了Promise,但没把这个结果存下来,反而直接把原函数数组apis传给了Promise.all——函数数组没法被Promise等待,自然拿不到任何响应数据。
问题2:循环中的Promise没有被统一等待
products.forEach不会等待内部的Promise完成,外面的dispatch会直接执行,这时候payload还没被填充任何API返回的数据,dispatch出去的自然是空的。
问题3:笔误与错误处理不当
代码里payload.get(companion.token)明显是笔误,应该是payload.get(product.token);另外catch里直接throw错误不会被正确捕获,也没法通知组件错误状态。
修正后的完整代码
COMPONENT.JSX
componentDidMount() { // 注意:callApis是thunk函数,需要通过dispatch调用 this.props.dispatch(callApis(this.props.products, this.props.profileId)); }
API.JS
const getContactDetails = (http, profileId) => (http.get(`https://www.fakeurl.com/${profileId}/contact`)); const getProductDetails = (http, profileId) => (http.get(`https://www.fakeurl.com/${profileId}/product`)); const callApis = (products, profileId) => async (dispatch) => { const payload = new Map(); try { // 收集所有产品对应的API操作Promise const allProductPromises = products.map(async (product) => { // 直接生成两个API的Promise实例 const apiPromises = [ getContactDetails(http, profileId), getProductDetails(http, profileId) ]; // 等待当前产品的两个API请求完成 const responses = await Promise.all(apiPromises); // 解析数据 const apiData = { contactData: getParsedContactData(responses[0]), productData: getParsedProductData(responses[1]) }; // 更新payload if (payload.has(product.token)) { payload.get(product.token).push(apiData); } else { payload.set(product.token, [apiData]); } }); // 等待所有产品的API请求+数据处理全部完成 await Promise.all(allProductPromises); // 所有操作完成后再dispatch dispatch({ type: FETCH_API_DATA, payload: payload }); } catch (err) { console.error('An error occurred ', err); // 可选:dispatch错误状态到store,方便组件处理 // dispatch({ type: FETCH_API_DATA_FAILED, error: err }); } }
关键修改说明
- 把
callApis改成async函数,用await统一等待所有异步操作 - 用
products.map代替forEach,收集每个产品对应的异步操作Promise,确保能等待全部完成 - 直接将API调用的Promise实例传入
Promise.all,保证能拿到响应结果 - 修正了
companion.token的笔误,改为正确的product.token - 优化错误处理,添加了错误状态的dispatch选项
内容的提问来源于stack exchange,提问作者Pranay
相关产品推荐
相关产品推荐

