12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow strict-local
- */
- 'use strict';
- const InteractionManager = require('./InteractionManager');
- /**
- * 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, delayMS: number) {
- this._delay = delayMS;
- 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(options: {abort: boolean, ...} = {abort: false}) {
- if (this._taskHandle) {
- this._taskHandle.cancel();
- if (!options.abort) {
- this._callback();
- }
- this._taskHandle = null;
- }
- }
- schedule() {
- if (this._taskHandle) {
- return;
- }
- const timeoutHandle = setTimeout(() => {
- this._taskHandle = InteractionManager.runAfterInteractions(() => {
- // 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();
- });
- }, this._delay);
- this._taskHandle = {cancel: () => clearTimeout(timeoutHandle)};
- }
- }
- module.exports = Batchinator;
|