react-native-reanimated: Promise is not working inside callback

Description

If worklet calls callback function - only body of this function is called. Functions scheduled for the next tick (promise) are not called (until some manul event)

const callWithPromise = () => {
  return Promise.resolve();
};

const Row = () => {
  return <View style={styles.row} />;
};

const Application = () => {
  const onSwipeCallback = useCallback(() => {
    console.log('[onSwipeCallback] was called');
    callWithPromise()
      .then(() => {
        console.log('[onSwipeCallback] promise then');
      })
      .catch(() => {
        console.log('[onSwipeCallback] promise catch');
      });
  }, []);

  return (
    <View style={styles.container}>
      <SwipableRow onSwipeLeft={onSwipeCallback} onSwipeRight={onSwipeCallback}>
        <Row />
      </SwipableRow>
    </View>
  );
};

This callback code is not working as expected. then callback should be called immediately, but it’s not.

Screenshots

Steps To Reproduce

Expected behavior

Promise should be scheduled and executed immidiately.

Actual behavior

Promise is not executed until some external event (touch screen)

Snack or minimal code example

SwipableRow.txt Application.txt

Package versions

  • React: 16.11.0
  • React Native: 0.62.2
  • React Native Reanimated: 2.0.0-alpha.5

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 23 (23 by maintainers)

Commits related to this issue

Most upvoted comments

So I was able to reproduce the problem on Android using code provided by @likern. On iOS it works alright.

It’s only a temporary solution I’m working on a proper one.

I can verify it’s not working by this code:

export default function App() {
  const value = useSharedValue(0);

  const p = () => {
    console.log('end');
    const cb = () => console.log('promise');
    (() => Promise.resolve(() => cb()))();
  };

  const handler = useAnimatedGestureHandler({
    onActive: (evt) => {
      value.value = withTiming(1, undefined, () => {
        p();
      });
    },
  });

  return (
    <View style={{ margin: 40 }}>
      <TapGestureHandler numberOfTaps={1} onGestureEvent={handler}>
        <Animated.View>
          <Text>Test</Text>
        </Animated.View>
      </TapGestureHandler>
    </View>
  );
}