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

React Native使用Reanimated调用setTimeout报fun.__callAsync错误如何解决

问题根因

  • 报错和moveBack未执行的核心原因是你通过runOnJS传递了translateX共享值作为参数:runOnJS的入参必须是可序列化的普通值,而共享值是UI线程的引用对象,无法跨线程序列化传递,直接导致函数调用失败。
  • 你不需要把共享值作为参数传递,共享值本身是在组件作用域声明的,moveBack可以直接访问它的引用。

修复方案(基于你原有实现)

  1. 修改moveBack函数,去掉入参,直接访问作用域内的共享值:
const moveBack = () => {
  console.log("TRANSLATEX: ", translateX.value);
  setTimeout(() => {
    // 用withTiming保证复位动画平滑
    translateX.value = withTiming(0);
  }, 2000);
}
  1. 修改手势的onEnd逻辑,调用runOnJS时不传共享值参数:
onEnd: event => {
  const shouldStick = translateX.value >= TRANSLATE_X_THRESHOULD;
  if (shouldStick) {
    translateX.value = withTiming(120);
    runOnJS(moveBack)();
  } else {
    translateX.value = withTiming(0);
  }
},

更优实现(无需跨线程调用,纯UI线程处理)

你完全不需要使用setTimeout和runOnJS,直接用Reanimated自带的withDelayAPI在UI线程完成延迟逻辑,性能更好也不会有线程通信问题:

const panGesture = useAnimatedGestureHandler<PanGestureHandlerGestureEvent>({
  onActive: event => {
    translateX.value = event.translationX;
    if (event.translationX <= 0) {
      translateX.value = 0;
    }
  },
  onEnd: event => {
    const shouldStick = translateX.value >= TRANSLATE_X_THRESHOULD;
    if (shouldStick) {
      // 先滑动到120位置,动画结束后延迟2秒自动复位
      translateX.value = withTiming(120, {}, () => {
        'worklet';
        return withDelay(2000, withTiming(0));
      });
    } else {
      translateX.value = withTiming(0);
    }
  },
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:15:06