mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
dc8d218077
Summary: Changelog: [Internal] Historically, Immediate API is implemented upon the React Native's internal microtask-y queue (known as "immediate queue"), which is the same queue Promise polyfill is operating on. To make React Native suitable of using the built-in Promises from JSVMs, which usually enqueues to the JSVM internal microtask queue and has no access to React Native microtask-y queue, we need to migrate the Immediate API to use the JSVM microtask queue as well to preserve the semantics of code relies on the interleaving of promises and immediates. To do that, this diff implement a shim layer for immediate APIs via the new `global.queueMicrotask` API (which enqueues to JSVM) in JS, by wrapping the immediate callback into a "microtask callback", which validate the `immediate ID` against `clearedImmediate` Set before invoking it. Reviewed By: RSNara Differential Revision: D29845305 fbshipit-source-id: c2ed3fed426a5316b1e0dfbfaad51706d1765d4d
68 lines
1.6 KiB
JavaScript
68 lines
1.6 KiB
JavaScript
/**
|
|
* 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
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
// Globally Unique Immediate ID.
|
|
let GUIID = 1;
|
|
|
|
// A global set of the currently cleared immediates.
|
|
const clearedImmediates: Set<number> = new Set();
|
|
|
|
/**
|
|
* Shim the setImmediate API on top of queueMicrotask.
|
|
* @param {function} func Callback to be invoked before the end of the
|
|
* current JavaScript execution loop.
|
|
*/
|
|
function setImmediate(callback: Function, ...args: any): number {
|
|
if (arguments.length < 1) {
|
|
throw new TypeError(
|
|
'setImmediate must be called with at least one argument (a function to call)',
|
|
);
|
|
}
|
|
if (typeof callback !== 'function') {
|
|
throw new TypeError(
|
|
'The first argument to setImmediate must be a function.',
|
|
);
|
|
}
|
|
|
|
const id = GUIID++;
|
|
// This is an edgey case in which the sequentially assigned ID has been
|
|
// "guessed" and "cleared" ahead of time, so we need to clear it up first.
|
|
if (clearedImmediates.has(id)) {
|
|
clearedImmediates.delete(id);
|
|
}
|
|
|
|
global.queueMicrotask(() => {
|
|
if (!clearedImmediates.has(id)) {
|
|
callback.apply(undefined, args);
|
|
} else {
|
|
// Free up the Set entry.
|
|
clearedImmediates.delete(id);
|
|
}
|
|
});
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* @param {number} immediateID The ID of the immediate to be clearred.
|
|
*/
|
|
function clearImmediate(immediateID: number) {
|
|
clearedImmediates.add(immediateID);
|
|
}
|
|
|
|
const immediateShim = {
|
|
setImmediate: setImmediate,
|
|
clearImmediate: clearImmediate,
|
|
};
|
|
|
|
module.exports = immediateShim;
|