Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Timers] Batch setImmediate handlers #1242

Closed
wants to merge 1 commit into from

Conversation

ide
Copy link
Contributor

@ide ide commented May 12, 2015

Wraps the setImmediate handlers in a batchUpdates call before they are synchronously executed at the end of the JS execution loop.

Test Plan: Added two setImmediate calls to componentDidMount in UIExplorerApp. Each handler calls setState, and componentWillUpdate logs its state. With this diff, we can see the state updates are successfully batched.

componentDidMount() {
  setImmediate(() => {
    console.log('immediate 1');
    this.setState({a: 1});
  });
  setImmediate(() => {
    console.log('immediate 2');
    this.setState({a: 2});
  });
},

componentWillUpdate(nextProps, nextState) {
  console.log('componentWillUpdate with next state.a =', nextState.a);
},

Before:

"immediate 1"
"componentWillUpdate with next state.a =", 1
"immediate 2"
"componentWillUpdate with next state.a =", 2

After:

"immediate 1"
"immediate 2"
"componentWillUpdate with next state.a =", 2

Addresses the batching issue in #1232. cc @vjeux @spicyj

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 12, 2015
@tadeuzagallo
Copy link
Contributor

I was looking into it before, but I thought on doing it on processBatch(), since the other functions basically don't get called directly...
You could do something like:

var flushedQueue;
React.batchedUpdates(() => {
  flushedQueue = guardReturn(...);
});
return flushedQueue;

@ide
Copy link
Contributor Author

ide commented May 12, 2015

I realized batchedUpdates needs to be inside of the guard. Update coming.

@ide
Copy link
Contributor Author

ide commented May 12, 2015

Looking some more, the current diff appears correct to me. Both batchedUpdate calls (the one in processBatch and the new one in _flushQueueUnguarded) run inside of the guard so errors should be handled correctly.

It's easy to reduce the batching to one batch by moving JSTimersExecution.callImmediates() inside of processBatch, but if RN's semantics are intended to match the web's in this case, I think we actually want two separate batchedUpdate calls so that the setImmediate handlers run after the native->JS calls.

@sophiebits
Copy link
Contributor

It is unintuitive to me that setImmediate calls would get batched together into the same React reconciliation. I'll have to think about it some more.

@ide
Copy link
Contributor Author

ide commented May 12, 2015

@spicyj totally understand. What if they were process.nextTick calls? The motivation behind this diff is to batch the following updates:

var resolve1, resolve2;
new Promise((resolve) => resolve1 = resolve).then(() => {
  this.setState({...});
});
new Promise((resolve) => resolve2 = resolve).then(() => {
  this.setState({...});
});

// Resolve both promises in the same run of the event loop
resolve1();
resolve2();

Promises internally schedule a microtask (in RN this currently means setImmediate) but we want to batch the updates.

One catch is that if we use native Promises then they won't call setImmediate nor nextTick so maybe this diff isn't the best approach anyway. Feel free to take or reject it.

@vjeux
Copy link
Contributor

vjeux commented May 14, 2015

@ide we can't use native promises as they don't respect React Native scheduling with the batch, so I don't think that's a big issue anyway

@vjeux
Copy link
Contributor

vjeux commented May 14, 2015

Actually, assigning to @spicyj since he has some thoughts on the matter.

@sophiebits
Copy link
Contributor

I think this is all right.

@sophiebits
Copy link
Contributor

@facebook-github-bot import

plz

@vjeux
Copy link
Contributor

vjeux commented Jun 1, 2015

@facebook-github-bot import

@vjeux
Copy link
Contributor

vjeux commented Jun 1, 2015

strange that it didn't work for you @spicyj

@facebook-github-bot
Copy link
Contributor

Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/439269476233905/int_phab to review.

@ide ide closed this in 2a6fe07 Jun 3, 2015
@sophiebits
Copy link
Contributor

This got reverted internally. Will try to re-land.

@sophiebits sophiebits reopened this Jun 4, 2015
@ide ide closed this Jul 2, 2015
@ide ide force-pushed the batch-immediates branch from 2829411 to e81e29f Compare July 2, 2015 19:01
@sophiebits
Copy link
Contributor

@ide Anything change here? Still had this on my (long) list of things to do.

@ide
Copy link
Contributor Author

ide commented Jul 4, 2015

@spicyj this issue should be open. I must have closed it when rebasing since it was merged once before being reverted. Reapplied the commit on top of master and retested.

@ide ide reopened this Jul 4, 2015
Wraps the setImmediate handlers in a `batchedUpdates` call before they are synchronously executed at the end of the JS execution loop.

Test Plan:
 Added two `setImmediate` calls to `componentDidMount` in UIExplorerApp. Each handler calls `setState`, and `componentWillUpdate` logs its state. With this diff, we can see the state updates are successfully batched.

```javascript
componentDidMount() {
  setImmediate(() => {
    console.log('immediate 1');
    this.setState({a: 1});
  });
  setImmediate(() => {
    console.log('immediate 2');
    this.setState({a: 2});
  });
},

componentWillUpdate(nextProps, nextState) {
  console.log('componentWillUpdate with next state.a =', nextState.a);
},
```

**Before:**

"immediate 1"
"componentWillUpdate with next state.a =", 1
"immediate 2"
"componentWillUpdate with next state.a =", 2

**After:**

"immediate 1"
"immediate 2"
"componentWillUpdate with next state.a =", 2
@ide ide force-pushed the batch-immediates branch from 510c69d to 6e30141 Compare September 1, 2015 06:30
@ide
Copy link
Contributor Author

ide commented Oct 9, 2015

Closing this because setImmediates were batched in 4c74f01.

@ide ide closed this Oct 9, 2015
ayushjainrksh pushed a commit to MLH-Fellowship/react-native that referenced this pull request Jul 2, 2020
…acebook#1242)

* imp: snack example for components

* revert pretter stuff
mganandraj pushed a commit to mganandraj/react-native that referenced this pull request Aug 5, 2022
* Manual version bump to 0.68.3

* Use react-native-macos instead of react-native in template version bump
@ide ide deleted the batch-immediates branch March 9, 2024 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants