From ea882b6f161409ff439b93dfa146431944a42d9d Mon Sep 17 00:00:00 2001 From: Alexander Blom Date: Fri, 4 Mar 2016 09:30:38 -0800 Subject: [PATCH] Immediate dispatch 0 time timers Summary: Calling setTimeout(f, 0) will currently schedule f to be called the next frame instead of immediately (which is how it behaves on iOS). This immediately calls back to JS and invokes the function. Reviewed By: astreet, tadeuzagallo Differential Revision: D3006125 fb-gh-sync-id: 9fa109ed82836a718cbb2e8cb21da4943d96f5f6 shipit-source-id: 9fa109ed82836a718cbb2e8cb21da4943d96f5f6 --- .../com/facebook/react/modules/core/Timing.java | 8 ++++++++ .../react/modules/timing/TimingModuleTest.java | 14 ++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java index b0bf332da..79a5b6b3f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java @@ -217,6 +217,14 @@ public final class Timing extends ReactContextBaseJavaModule implements Lifecycl long adjustedDuration = (long) Math.max( 0, jsSchedulingTime - SystemClock.currentTimeMillis() + duration); + if (duration == 0 && !repeat) { + WritableArray timerToCall = Arguments.createArray(); + timerToCall.pushInt(callbackID); + getReactApplicationContext().getJSModule(executorToken, JSTimersExecution.class) + .callTimers(timerToCall); + return; + } + long initialTargetTime = SystemClock.nanoTime() / 1000000 + adjustedDuration; Timer timer = new Timer(executorToken, callbackID, initialTargetTime, duration, repeat); synchronized (mTimerGuard) { diff --git a/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java b/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java index 1597d84e3..e6185a8f0 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/modules/timing/TimingModuleTest.java @@ -110,7 +110,7 @@ public class TimingModuleTest { @Test public void testSimpleTimer() { mTiming.onHostResume(); - mTiming.createTimer(mExecutorTokenMock, 1, 0, 0, false); + mTiming.createTimer(mExecutorTokenMock, 1, 1, 0, false); stepChoreographerFrame(); verify(mJSTimersMock).callTimers(JavaOnlyArray.of(1)); reset(mJSTimersMock); @@ -120,7 +120,7 @@ public class TimingModuleTest { @Test public void testSimpleRecurringTimer() { - mTiming.createTimer(mExecutorTokenMock, 100, 0, 0, true); + mTiming.createTimer(mExecutorTokenMock, 100, 1, 0, true); mTiming.onHostResume(); stepChoreographerFrame(); verify(mJSTimersMock).callTimers(JavaOnlyArray.of(100)); @@ -133,7 +133,7 @@ public class TimingModuleTest { @Test public void testCancelRecurringTimer() { mTiming.onHostResume(); - mTiming.createTimer(mExecutorTokenMock, 105, 0, 0, true); + mTiming.createTimer(mExecutorTokenMock, 105, 1, 0, true); stepChoreographerFrame(); verify(mJSTimersMock).callTimers(JavaOnlyArray.of(105)); @@ -147,7 +147,7 @@ public class TimingModuleTest { @Test public void testPausingAndResuming() { mTiming.onHostResume(); - mTiming.createTimer(mExecutorTokenMock, 41, 0, 0, true); + mTiming.createTimer(mExecutorTokenMock, 41, 1, 0, true); stepChoreographerFrame(); verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41)); @@ -163,6 +163,12 @@ public class TimingModuleTest { verify(mJSTimersMock).callTimers(JavaOnlyArray.of(41)); } + @Test + public void testSetTimeoutZero() { + mTiming.createTimer(mExecutorTokenMock, 100, 0, 0, false); + verify(mJSTimersMock).callTimers(JavaOnlyArray.of(100)); + } + private static class PostFrameCallbackHandler implements Answer { private Choreographer.FrameCallback mFrameCallback;