Skip to content

Commit

Permalink
Split up createTimer into two methods, createTimer and createTimerFor…
Browse files Browse the repository at this point in the history
…NextFrame

Summary:
This diff adds nuance to timer creation.  Imagine the following bit of JS:

```
    setTimeout(() => {
      console.log("Timeout")
    }, 0);
    setImmediate(() => {
      setNine("Immediate");
    });
```

In classic RN, `setTimeout` will be called async by the bridge, immediate is implemented in JS, so the ordering of logs will be:

1. Immediate
2. Timeout

In bridgeless RN `setTimeout` is called sync, so the ordering of the logs is:

1. Timeout
2. Immediate

In order to preserve ordering, this diff adds a timer creation method which doesn't immediately invoke it, but waits one frame to do so.

This PR does the same thing for android, and explains the reasoning for preserving behaviour (some products may rely on this behaviour) f054928

Reviewed By: ejanzer

Differential Revision: D17535639

fbshipit-source-id: 3f734c420a6a95be2ee10e8d6ac48adc79ef1c96
  • Loading branch information
Peter Argany authored and facebook-github-bot committed Sep 25, 2019
1 parent 1bfd15c commit a6a6dbe
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
8 changes: 4 additions & 4 deletions React/Modules/RCTTiming.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
@interface RCTTiming : NSObject <RCTBridgeModule, RCTInvalidating, RCTFrameUpdateObserver>

- (instancetype)initWithDelegate:(id<RCTTimingDelegate>) delegate;
- (void)createTimer:(nonnull NSNumber *)callbackID
duration:(NSTimeInterval)jsDuration
jsSchedulingTime:(NSDate *)jsSchedulingTime
repeats:(BOOL)repeats;
- (void)createTimerForNextFrame:(nonnull NSNumber *)callbackID
duration:(NSTimeInterval)jsDuration
jsSchedulingTime:(NSDate *)jsSchedulingTime
repeats:(BOOL)repeats;
- (void)deleteTimer:(nonnull NSNumber *)timerID;

@end
Expand Down
18 changes: 18 additions & 0 deletions React/Modules/RCTTiming.m
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ - (void)timerDidFire
}

/**
* A method used for asynchronously creating a timer. If the timer has already expired,
* (based on the provided jsSchedulingTime) then it will be immediately invoked.
*
* There's a small difference between the time when we call
* setTimeout/setInterval/requestAnimation frame and the time it actually makes
* it here. This is important and needs to be taken into account when
Expand All @@ -372,6 +375,21 @@ - (void)timerDidFire
return;
}

[self createTimerForNextFrame:callbackID
duration:jsDuration
jsSchedulingTime:jsSchedulingTime
repeats:repeats];
}

/**
* A method used for synchronously creating a timer. The timer will not be invoked until the
* next frame, regardless of whether it has already expired (i.e. jsSchedulingTime is 0).
*/
- (void)createTimerForNextFrame:(nonnull NSNumber *)callbackID
duration:(NSTimeInterval)jsDuration
jsSchedulingTime:(NSDate *)jsSchedulingTime
repeats:(BOOL)repeats
{
NSTimeInterval jsSchedulingOverhead = MAX(-jsSchedulingTime.timeIntervalSinceNow, 0);

NSTimeInterval targetTime = jsDuration - jsSchedulingOverhead;
Expand Down

0 comments on commit a6a6dbe

Please sign in to comment.