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

如何在执行异步函数的同时运行另一个函数?

如何在执行异步函数的同时运行另一个函数?

嘿,这个需求其实挺常见的——想同时启动异步任务和动画,等异步任务结束后再停掉动画对吧?我给你几个实用的方案,完全不用依赖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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:43:06