使用Redux-Thunk/Redux-Firebase上传图片至Firebase Storage时Async/Await异常求助
问题分析与代码修正
我帮你看看问题出在哪哈~你遇到的result未等待Firebase返回URL的问题,核心是Async/await和Promise的使用细节没处理到位,主要有两个关键问题:
问题1:Promise未被正确返回给Promise.all
你在ads.image.map()的回调函数里创建了Promise,但没有return这个Promise!这就导致Promise.all实际接收的是一个充满undefined的数组,根本不会等待上传操作完成,自然result会立刻变成一堆undefined,等不到Firebase的返回结果。
问题2:数据整合逻辑错误
你在每个Promise内部都重新初始化了data = {...ads, imageUrl: []},这样每次循环都会生成一个新的对象,最后result里的每个元素都是只包含当前图片URL的独立对象,而不是把所有图片URL整合到同一个ads对象里,后续也没法直接用这个result发后端。
修正后的完整代码
export const postAds = (ads) => { return async (dispatch, getState, { getFirebase }) => { const firebase = getFirebase(); try { // 先初始化基础数据,拷贝原ads内容并创建空的imageUrl数组 const finalAdsData = { ...ads, imageUrl: [] }; // 用Promise.all等待所有图片上传完成,注意map回调要return Promise const uploadedImages = await Promise.all( ads.image.map((imageItem) => { return new Promise((resolve, reject) => { const uploadTask = firebase .storage() .ref(`images/${imageItem.file.name}`) .put(imageItem.file); uploadTask.on( "state_changed", (snapshot) => { const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log(`图片 ${imageItem.file.name} 上传进度:${progress}%`); }, // 上传失败时触发reject,同时dispatch错误action (err) => { dispatch({ type: "IMAGE_UPLOAD_ERROR", err }); reject(err); }, // 上传完成后获取下载URL () => { uploadTask.snapshot.ref .getDownloadURL() .then((downloadURL) => { dispatch({ type: "IMAGE_UPLOAD_SUCCESS", payload: downloadURL }); // 只返回当前图片的URL和对应的alt,后续统一整合 resolve({ downloadURL, alt: imageItem.alt }); }) .catch(reject); // 捕获获取URL时的错误 } ); }); }) ); // 把所有上传成功的图片URL和alt整合到finalAdsData里 uploadedImages.forEach((img) => { finalAdsData.imageUrl.push(img); }); console.log("所有图片上传完成,最终待发送数据:", finalAdsData); // 这里调用axios发送到后端,现在所有URL都已准备好 // await axios.post("/your-backend-api-url", finalAdsData); // 可以dispatch一个广告发布成功的action // dispatch({ type: "POST_ADS_SUCCESS", payload: finalAdsData }); } catch (err) { console.error("广告发布流程出错:", err); // dispatch({ type: "POST_ADS_ERROR", err }); } }; };
关键修改说明
- 正确返回Promise:在
ads.image.map()的回调里加上return new Promise(...),让Promise.all能正确收集所有上传任务的Promise,等待它们全部完成后再继续执行。 - 统一数据整合:把最终要发送的
finalAdsData初始化放在循环外面,每个Promise只返回当前图片的URL和alt,等所有上传完成后,再把这些数据统一合并到finalAdsData的imageUrl数组里,保证数据结构正确。 - 完善错误处理:在上传错误回调里调用
reject(err),同时捕获getDownloadURL的错误,确保任何一步出错都会被外层的try/catch捕获,避免流程卡死。 - 清晰的流程顺序:现在代码的逻辑是:初始化数据 → 等待所有图片上传并获取URL → 整合URL到数据 → 发送到后端,完全符合你需要的流程,不会再出现未等待的问题。
内容的提问来源于stack exchange,提问作者hadi tedi
相关产品推荐
相关产品推荐

