如何在执行异步函数的同时运行另一个函数?
如何在执行异步函数的同时运行另一个函数?
嘿,这个需求其实挺常见的——想同时启动异步任务和动画,等异步任务结束后再停掉动画对吧?我给你几个实用的方案,完全不用依赖useEffect状态,直接在点击事件里就能搞定:
方案一:用布尔变量控制动画循环
核心思路就是同时启动异步任务和动画,然后在异步任务完成后切换一个标志,让动画循环自动退出。
如果你的animateFunc是返回Promise的异步帧动画(比如封装了requestAnimationFrame),可以这么写:
const handleClick = async () => { let shouldStop = false; // 先启动异步任务,不用await,让它在后台跑 const asyncTask = asyncFunc(); // 启动动画循环 const runAnimation = async () => { while (!shouldStop) { await animateFunc(); // 每完成一帧动画再进入下一轮 } }; runAnimation(); // 等异步任务完成后,切换停止标志 await asyncTask; shouldStop = true; };
如果animateFunc是同步的动画逻辑,那得用requestAnimationFrame来避免阻塞主线程:
const handleClick = async () => { let shouldStop = false; const asyncTask = asyncFunc(); function animateFrame() { if (shouldStop) return; // 执行单帧动画逻辑 animateFunc(); // 调度下一帧 requestAnimationFrame(animateFrame); } // 启动动画 requestAnimationFrame(animateFrame); // 异步任务完成后停止动画 await asyncTask; shouldStop = true; };
方案二:用AbortController(更优雅的现代方案)
如果你觉得维护布尔变量有点麻烦,可以用浏览器原生的AbortController来发送停止信号,代码会更简洁:
const handleClick = async () => { const controller = new AbortController(); const signal = controller.signal; // 启动异步任务 const asyncTask = asyncFunc(); // 启动动画循环,监听中止信号 const runAnimation = async () => { while (!signal.aborted) { await animateFunc(); } }; runAnimation(); // 异步任务完成后,发送中止信号 await asyncTask; controller.abort(); };
关键注意点
一定要确保你的动画逻辑不会阻塞主线程!如果animateFunc是一个无限同步for循环,那JS单线程的特性会让异步任务根本没机会执行——必须把动画拆分成逐帧执行的逻辑(用requestAnimationFrame或setTimeout),这样主线程才有空隙处理异步任务的回调。
这样既不用依赖组件状态,又能实现“同时启动、异步完成后停动画”的需求啦~
备注:内容来源于stack exchange,提问作者Red Baron
相关产品推荐
相关产品推荐

