You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JavaScript:如何在所有Promise循环完成后执行单次操作

解决Promise.all后仅执行一次操作的问题

你的核心问题是没正确等待所有Promise完成就调用了doSomethingWithResults,而且原代码里的uploadTask事件回调会单独更新状态,导致组件多次重渲染、操作重复触发。直接用if语句没用,因为状态更新是异步的,根本没法靠它判断所有异步任务是否结束。

给你修正后的方案,核心是把所有异步逻辑都纳入Promise.all的等待范围,等全部完成后再统一处理:

const [results, setResults] = useState([])

const handleSubmit = async (e) => {
    e.preventDefault();
    // 给每个thing生成完整的Promise,包含所有异步步骤
    const promises = stuff.map(async (thing) => {
        // 先等待digitaloceantask的操作完成,拿到uploadTask
        const uploadTask = await digitaloceantask.something(thing);
        
        // 把uploadTask的state_changed事件转为Promise,确保等待到结果
        return new Promise((resolve) => {
            uploadTask.on("state_changed", async () => {
                // 等待dosomething完成,拿到结果
                const result = await dosomething();
                // 把当前thing的结果传给Promise.all
                resolve(result);
            });
        });
    });

    // 等待所有Promise全部完成,拿到完整结果数组
    const allResults = await Promise.all(promises);
    
    // 一次性更新状态,避免多次重渲染
    setResults(allResults);
    
    // 所有任务都完成了,这里只会执行一次
    doSomethingWithResults(allResults);
}

关键说明:

  • 把handleSubmit改成async函数:用await等待Promise.all,确保所有异步任务结束后再执行后续操作。
  • 统一包装异步逻辑:每个thing对应的digitaloceantask操作、uploadTask事件处理、dosomething都被包装成一个Promise,确保没有遗漏任何异步步骤。
  • 一次性更新状态:不再在单个回调里零散更新results,而是等所有结果都拿到后一次性设置,避免组件多次重渲染。
  • 直接用allResults传参:状态更新是异步的,setResults后立刻访问results拿不到最新值,直接用Promise.all返回的allResults更可靠。

内容的提问来源于stack exchange,提问作者Mars2024

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:36:18