遍历Firestore获取购物车数据时得到Promise列表的问题排查
问题说明
我的yourCarts变量是字符串类型ID的列表,格式为yourCarts = [id1, id2, id3, .....];。我希望遍历该列表,为每个ID从Firestore获取对应文档,最终得到一个对象列表并更新组件状态,但目前得到的是Promise列表而非预期的对象列表。以下是我的代码:
{ getYourCartList(); async function getYourCartList() { const userRefID = localStorage.getItem("uid"); try { const userDoc = (await getDoc(doc(db, "clients", userRefID))).data(); const yourCarts = userDoc?.yourCarts; async function getCart(cartRefID) { try { const snapShot = ( await getDoc(doc(db, "products", cartRefID)) ).data(); return { ...snapShot, id: cartRefID }; } catch (error) { //...... return { id: cartRefID }; } } if (yourCarts) { setShoppingCart(yourCarts.map((cartRefID) => getCart(cartRefID))); } console.log("cartlist : ", cartlist); } catch (error) { console.log("error occurs"); } } }
错误原因
- async函数返回值为Promise:
getCart是异步函数,调用后会直接返回Promise对象。用yourCarts.map(cartRefID => getCart(cartRefID))得到的是一个Promise数组,直接传给setShoppingCart会把Promise列表存在状态里,而非解析后的对象。 - 状态更新的异步性:
console.log("cartlist : ", cartlist)无法获取最新状态,因为React的状态更新是异步操作,执行这行代码时状态还未完成更新。
修正代码
{ getYourCartList(); async function getYourCartList() { const userRefID = localStorage.getItem("uid"); try { const userDoc = (await getDoc(doc(db, "clients", userRefID))).data(); const yourCarts = userDoc?.yourCarts; async function getCart(cartRefID) { try { const snapShot = (await getDoc(doc(db, "products", cartRefID))).data(); return { ...snapShot, id: cartRefID }; } catch (error) { // 处理错误逻辑 return { id: cartRefID }; } } if (yourCarts) { // 用Promise.all等待所有异步请求完成,拿到解析后的对象数组 const resolvedCarts = await Promise.all(yourCarts.map(cartRefID => getCart(cartRefID))); setShoppingCart(resolvedCarts); } } catch (error) { console.log("error occurs", error); } } }
额外提示
如果需要确认状态更新后的结果,建议使用useEffect监听cartlist变化,在回调中打印:
useEffect(() => { console.log("cartlist updated: ", cartlist); }, [cartlist]);
内容的提问来源于stack exchange,提问作者Ayush
相关产品推荐
相关产品推荐

