React Native使用Reanimated调用setTimeout报fun.__callAsync错误如何解决
问题根因
- 报错和
moveBack未执行的核心原因是你通过runOnJS传递了translateX共享值作为参数:runOnJS的入参必须是可序列化的普通值,而共享值是UI线程的引用对象,无法跨线程序列化传递,直接导致函数调用失败。 - 你不需要把共享值作为参数传递,共享值本身是在组件作用域声明的,
moveBack可以直接访问它的引用。
修复方案(基于你原有实现)
- 修改
moveBack函数,去掉入参,直接访问作用域内的共享值:
const moveBack = () => { console.log("TRANSLATEX: ", translateX.value); setTimeout(() => { // 用withTiming保证复位动画平滑 translateX.value = withTiming(0); }, 2000); }
- 修改手势的
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
相关产品推荐
相关产品推荐

