JS调用Firebase Storage返回看似空的对象数组问题排查求助
问题根因
- 所有Firebase的
listAll()、getDownloadURL()都是异步Promise接口,代码不会等待它们执行完成再往下走。你声明空数组后直接同步返回,此时网络请求还没完成,数组自然是空的。 - 控制台展开能看到数据是因为打印的是数组的引用,你点击展开时异步请求已经执行完成,数组已经被后续填充了内容,但代码逻辑执行到判断
allImages.length的时间点,数组确实是空的,所以最终返回空数组。
修正方案
把所有异步逻辑用async/await改写,用Promise.all等待所有子异步任务完成再返回结果:
import { flowerThumbsRef, flowersRef, } from "../../../../utils/firebase/firebase"; import _ from "lodash"; // 获取Firebase Storage内所有物品列表,构造对象存入数组 export const getAllImages = async () => { const res = await flowersRef.listAll(); // 构造所有获取下载地址的异步任务数组 const imageTasks = res.items.map(async (item) => { const url = await item.getDownloadURL(); return { name: item.name, link: url, }; }); // 等待所有下载地址获取完成再返回完整数组 return Promise.all(imageTasks); }; // 获取Firebase Storage内所有缩略图列表,构造对象存入数组 export const getAllThumbnails = async () => { const res = await flowerThumbsRef.listAll(); const thumbTasks = res.items.map(async (item) => { const newName = item.name.replace("_200x200", ""); const url = await item.getDownloadURL(); return { name: newName, link: url, }; }); return Promise.all(thumbTasks); }; // 执行上述函数构造对象数组 export const createItems = async () => { // 等待两个资源列表全部拉取完成 const allImages = await getAllImages(); const allThumbs = await getAllThumbnails(); let items = []; allImages.forEach((item) => { let linkedThumb = _.find(allThumbs, (i) => i.name === item.name); // 增加判空逻辑避免匹配不到时报错 if (linkedThumb) { items.push({ itemId: item.name, mediaUrl: linkedThumb.link, metaData: { type: "image", link: item.link, }, }); } }); return items; }; // 调用异步函数需要等待结果,如果环境不支持顶层await,用.then处理 const allItems = await createItems(); console.log(allItems); // 不支持顶层await的写法: // createItems().then(allItems => { // console.log(allItems); // // 后续业务逻辑都写在这里 // })
内容的提问来源于stack exchange,提问作者mavrik83
相关产品推荐
相关产品推荐

