mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
29a0d7c3b2
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47690 Creates a feature flag to evalute the impact of disabling `InteractionManager` in `Batchinator` and synchronously invoking callbacks after the timeout. This also deletes the `dispose` arguments in `Batchinator` that were unused. Changelog: [Internal] Reviewed By: bvanderhoof Differential Revision: D66139643 fbshipit-source-id: d17bab0cd25c0c69779686cb435c063f707255e4
86 lines
2.5 KiB
JavaScript
86 lines
2.5 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
import {InteractionManager} from 'react-native';
|
|
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
|
|
|
|
/**
|
|
* A simple class for batching up invocations of a low-pri callback. A timeout is set to run the
|
|
* callback once after a delay, no matter how many times it's scheduled. Once the delay is reached,
|
|
* InteractionManager.runAfterInteractions is used to invoke the callback after any hi-pri
|
|
* interactions are done running.
|
|
*
|
|
* Make sure to cleanup with dispose(). Example:
|
|
*
|
|
* class Widget extends React.Component {
|
|
* _batchedSave: new Batchinator(() => this._saveState, 1000);
|
|
* _saveSate() {
|
|
* // save this.state to disk
|
|
* }
|
|
* componentDidUpdate() {
|
|
* this._batchedSave.schedule();
|
|
* }
|
|
* componentWillUnmount() {
|
|
* this._batchedSave.dispose();
|
|
* }
|
|
* ...
|
|
* }
|
|
*/
|
|
class Batchinator {
|
|
_callback: () => void;
|
|
_delay: number;
|
|
_taskHandle: ?{cancel: () => void, ...};
|
|
|
|
constructor(callback: () => void, delay: number) {
|
|
this._delay = delay;
|
|
this._callback = callback;
|
|
}
|
|
|
|
/*
|
|
* Cleanup any pending tasks.
|
|
*
|
|
* By default, if there is a pending task the callback is run immediately. Set the option abort to
|
|
* true to not call the callback if it was pending.
|
|
*/
|
|
dispose(): void {
|
|
if (this._taskHandle) {
|
|
this._taskHandle.cancel();
|
|
this._taskHandle = null;
|
|
}
|
|
}
|
|
|
|
schedule(): void {
|
|
if (this._taskHandle) {
|
|
return;
|
|
}
|
|
const invokeCallback = () => {
|
|
// Note that we clear the handle before invoking the callback so that if the callback calls
|
|
// schedule again, it will actually schedule another task.
|
|
this._taskHandle = null;
|
|
this._callback();
|
|
};
|
|
|
|
const timeoutHandle = setTimeout(
|
|
// NOTE: When shipping this, delete `Batchinator` instead of only these
|
|
// lines of code. Without `InteractionManager`, it's just a `setTimeout`.
|
|
ReactNativeFeatureFlags.disableInteractionManagerInBatchinator()
|
|
? invokeCallback
|
|
: () => {
|
|
this._taskHandle =
|
|
InteractionManager.runAfterInteractions(invokeCallback);
|
|
},
|
|
this._delay,
|
|
);
|
|
this._taskHandle = {cancel: () => clearTimeout(timeoutHandle)};
|
|
}
|
|
}
|
|
|
|
module.exports = Batchinator;
|