为什么await Promise返回结果后,赋值的状态变量仍为空?
问题根源
核心问题出在GetAllForms函数的异步逻辑实现上:Array.prototype.forEach不支持等待异步回调执行完成。你给forEach传入了async回调函数,但forEach本身不会等待这些异步函数的Promise完成,就直接执行了后面的return dataFormattedArray语句,所以返回的数组在代码执行到return节点时确实是空的。
你直接打印data能看到内容是浏览器控制台的特性:打印引用类型时保存的是对象的引用,你手动展开控制台打印结果的时候,异步回调已经执行完、数组已经被填充,所以能看到内容,但实际代码运行到赋值、setAllForms的时间点,数组还是空值。
修复方案
把GetAllForms里的forEach遍历替换为map生成Promise数组,再用Promise.all等待所有异步任务执行完成后再返回结果:
export async function GetAllForms() { const formRef = await dbForms.collection("forms"); const snapshot = await formRef.get(); // 用map生成所有异步处理的Promise数组 const dataPromises = snapshot.docs.map(async doc => { const docData = doc.data() as IForms const aux = [] as FormsData[]; for (const id of docData.formsFieldId) { const test = await GetOneFormsField(id); aux.push(test); } return { ...docData, formsFieldId: [...aux] }; }) // 等待所有Promise执行完成,拿到最终数组 const dataFormattedArray = await Promise.all(dataPromises); return dataFormattedArray; }
额外说明
你执行setAllForms后立刻查看allForms为空,还有React的特性原因:React的状态更新是批量异步执行的,setAllForms调用后不会立刻修改当前作用域下的allForms变量,需要等组件重新渲染后,新的allForms值才会生效。如果需要确认状态是否更新成功,可以用useEffect监听allForms的变化:
useEffect(() => { console.log('allForms已更新:', allForms); }, [allForms])
内容的提问来源于stack exchange,提问作者Adrian Valdes
相关产品推荐
相关产品推荐

