连续查询Firebase Storage时仅第一个调用返回正确结果问题排查
问题根因
你代码中两个获取资源列表的函数都存在异步等待逻辑缺失的问题:
forEach遍历中传入的async回调函数之间是独立执行的,forEach本身不会等待所有异步回调执行完成,会直接执行后续的return语句- 你返回的
images数组在函数返回时还没有完成所有getDownloadURL请求的执行,本质是空数组 - 控制台点击展开后才显示内容,是因为控制台打印的是数组的引用,后续异步请求完成往数组中插入数据后,你展开引用就能读取到最新值,第一个函数看起来正常只是时序巧合,比如它的请求返回速度刚好快于打印时机,并非没有问题。
修复方案
将forEach遍历改为map生成Promise数组,配合Promise.all等待所有异步请求完成后再返回结果,修改后的代码如下:
import { flowersThumbRef, flowersFullRef, } from "../../../../utils/firebase/firebase"; // 获取Firebase Storage中所有物品列表,构造对象推入数组后返回 export const getAllImages = async () => { const response = await flowersFullRef.listAll(); // 为每一个资源项生成异步处理Promise const imagePromises = response.items.map(async (item) => { const imgUrl = await item.getDownloadURL(); return { name: item.name, link: imgUrl, }; }); // 等待所有Promise执行完成,返回完整结果数组 return Promise.all(imagePromises); }; // 获取Firebase Storage中所有缩略图列表,构造对象推入数组后返回 export const getAllThumbnails = async () => { const response = await flowersThumbRef.listAll(); const imagePromises = response.items.map(async (item) => { const imgUrl = await item.getDownloadURL(); return { name: item.name, link: imgUrl, }; }); return Promise.all(imagePromises); }; // 执行上述两个查询函数 export const createItems = async () => { const allImages = await getAllImages(); const allThumbs = await getAllThumbnails(); console.log(allImages); console.log(allThumbs); }; createItems();
补充说明
修改后两个函数都会等待所有资源的下载地址请求完成后才返回完整数组,不会再出现打印时空数组的问题。如果对性能有要求,你还可以把createItems里的两个await改为用Promise.all并行执行,减少总等待时间:
export const createItems = async () => { const [allImages, allThumbs] = await Promise.all([getAllImages(), getAllThumbnails()]); console.log(allImages); console.log(allThumbs); };
内容的提问来源于stack exchange,提问作者mavrik83
相关产品推荐
相关产品推荐

