React&JavaScript:为何useEffect中forEach计算后res仍为初始值0?
问题解析与解决办法
问题根源
forEach不支持等待内部的异步操作,你在forEach里写的async回调函数会被立刻触发,但forEach本身不会停留等待异步任务完成。addClaimableAmount函数里,res初始值是0,刚启动forEach里的异步任务,函数就直接返回了res,所以外部拿到的还是初始的0。而内部的console.log(res)是在异步请求完成后才执行的,那时候res已经更新,所以能看到正确结果。
解决办法
方案1:用for...of循环(串行执行异步请求)
把forEach换成for...of,它能配合async/await等待每个异步操作完成后再继续:
useEffect(() => { const addClaimableAmount = async () => { let res = 0; for (const value of ENDED) { const response = await getEstimatedAPRByStakeId(value.stakeId); res += parseInt(response.estimatedReward); res += parseInt(value.amount); console.log(res); } return res; }; // 异步函数需要用await获取结果,这里用立即执行异步函数 (async () => { const res = await addClaimableAmount(); console.log(res); })(); }, [ENDED]);
方案2:用Promise.all(并行执行异步请求,效率更高)
如果想同时发起所有异步请求,等全部完成后再计算总和,用这个方案:
useEffect(() => { const addClaimableAmount = async () => { // 把每个项的计算逻辑包装成Promise,返回当前项的贡献值 const promiseList = ENDED.map(async value => { const response = await getEstimatedAPRByStakeId(value.stakeId); return parseInt(response.estimatedReward) + parseInt(value.amount); }); // 等待所有Promise完成,再把结果求和 const allAmounts = await Promise.all(promiseList); return allAmounts.reduce((total, current) => total + current, 0); }; (async () => { const res = await addClaimableAmount(); console.log(res); })(); }, [ENDED]);
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

