React+Redux中Promise与Set timeout结合的问题排查
分析你的Promise延迟操作问题
Hey there! Let's break down what's likely throwing off your Promise-based delay logic for your prototype project.
问题核心根源
你在Promise内部用_.forEach处理敌人的延迟操作,但_.forEach是同步遍历方法——它只会一股脑执行完所有回调函数,完全不会等待回调里的异步/延迟操作完成。这就导致你的enemyTurnPromise要么提前resolve(比如你在回调里随便找个地方调用了resolve),要么一直处于pending状态(忘了正确触发resolve),自然和你预期的延迟效果不符。
修正方案
要让Promise正确等待所有延迟操作完成,你需要改用能跟踪异步任务的遍历方式,这里给你两种常用的解决思路:
方案1:并行处理所有敌人操作(用Promise.all + map)
如果敌人的操作不需要严格按顺序执行,这种方式效率更高:
if(nextProps.mechanics.turn === 'enemy'){ const enemyTurnPromise = new Promise((resolve, reject) => { // 把每个敌人的延迟操作包装成独立Promise const enemyActionPromises = this.props.enemies.map((enemy, index) => { return new Promise((actionResolve) => { // 这里写你的延迟操作逻辑,比如setTimeout模拟敌人思考/行动 setTimeout(() => { // 执行敌人的具体操作,比如攻击、移动等 console.log(`Enemy ${index} completed their action`); actionResolve(); }, 800); // 自定义延迟时长 }); }); // 等待所有敌人的Promise都完成后,再resolve主Promise Promise.all(enemyActionPromises).then(resolve).catch(reject); }); // 后续操作:所有敌人完成回合后执行 enemyTurnPromise.then(() => { console.log("All enemies have finished their turn!"); // 这里可以切换回合、更新游戏状态等 }); }
方案2:顺序处理敌人操作(用for...of + async/await)
如果需要敌人按顺序依次行动(比如先手敌人先出手),这种方式更直观:
if(nextProps.mechanics.turn === 'enemy'){ // 用自执行async函数包装顺序逻辑 const enemyTurnPromise = (async () => { for (const [index, enemy] of this.props.enemies.entries()) { // 等待当前敌人的延迟操作完成,再处理下一个 await new Promise((actionResolve) => { setTimeout(() => { console.log(`Enemy ${index} took their turn`); // 执行敌人的操作逻辑 actionResolve(); }, 1000); }); } })(); enemyTurnPromise.then(() => { console.log("Enemy turn finished in sequence!"); // 后续游戏逻辑 }); }
重要小提醒
- 一定要确保Promise的
resolve或reject被触发,不然Promise会一直挂起,可能导致后续逻辑卡死或者内存泄漏; - 如果你的延迟操作涉及React状态更新,记得结合React的状态更新机制(比如用
useEffect或者setState的回调),避免出现状态不同步的问题。
内容的提问来源于stack exchange,提问作者Matti Mazur
相关产品推荐
相关产品推荐

