RN: Clean JSTimersExecution JS

Reviewed By: sahrens

Differential Revision: D3539098

fbshipit-source-id: f17a35c5d6a45627bd6961b6b06266fe254d3976
This commit is contained in:
Tim Yung 2016-07-11 11:23:46 -07:00 committed by Facebook Github Bot 7
parent ed4db631fa
commit 1db781316b
1 changed files with 31 additions and 23 deletions

View File

@ -10,11 +10,12 @@
*/ */
'use strict'; 'use strict';
var invariant = require('fbjs/lib/invariant'); const Systrace = require('Systrace');
var keyMirror = require('fbjs/lib/keyMirror');
var performanceNow = require('fbjs/lib/performanceNow'); const invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning'); const keyMirror = require('fbjs/lib/keyMirror');
var Systrace = require('Systrace'); const performanceNow = require('fbjs/lib/performanceNow');
const warning = require('fbjs/lib/warning');
let hasEmittedTimeDriftWarning = false; let hasEmittedTimeDriftWarning = false;
@ -23,7 +24,7 @@ let hasEmittedTimeDriftWarning = false;
* external clock signal, all that's stored here is timerID, timer type, and * external clock signal, all that's stored here is timerID, timer type, and
* callback. * callback.
*/ */
var JSTimersExecution = { const JSTimersExecution = {
GUID: 1, GUID: 1,
Type: keyMirror({ Type: keyMirror({
setTimeout: null, setTimeout: null,
@ -43,9 +44,13 @@ var JSTimersExecution = {
* if it was a one time timer (setTimeout), and not unregister it if it was * if it was a one time timer (setTimeout), and not unregister it if it was
* recurring (setInterval). * recurring (setInterval).
*/ */
callTimer: function(timerID) { callTimer(timerID) {
warning(timerID <= JSTimersExecution.GUID, 'Tried to call timer with ID ' + timerID + ' but no such timer exists'); warning(
var timerIndex = JSTimersExecution.timerIDs.indexOf(timerID); timerID <= JSTimersExecution.GUID,
'Tried to call timer with ID %s but no such timer exists.',
timerID
);
const timerIndex = JSTimersExecution.timerIDs.indexOf(timerID);
// timerIndex of -1 means that no timer with that ID exists. There are // timerIndex of -1 means that no timer with that ID exists. There are
// two situations when this happens, when a garbage timer ID was given // two situations when this happens, when a garbage timer ID was given
// and when a previously existing timer was deleted before this callback // and when a previously existing timer was deleted before this callback
@ -54,8 +59,8 @@ var JSTimersExecution = {
if (timerIndex === -1) { if (timerIndex === -1) {
return; return;
} }
var type = JSTimersExecution.types[timerIndex]; const type = JSTimersExecution.types[timerIndex];
var callback = JSTimersExecution.callbacks[timerIndex]; const callback = JSTimersExecution.callbacks[timerIndex];
// Clear the metadata // Clear the metadata
if (type === JSTimersExecution.Type.setTimeout || if (type === JSTimersExecution.Type.setTimeout ||
@ -70,7 +75,7 @@ var JSTimersExecution = {
type === JSTimersExecution.Type.setImmediate) { type === JSTimersExecution.Type.setImmediate) {
callback(); callback();
} else if (type === JSTimersExecution.Type.requestAnimationFrame) { } else if (type === JSTimersExecution.Type.requestAnimationFrame) {
var currentTime = performanceNow(); const currentTime = performanceNow();
callback(currentTime); callback(currentTime);
} else { } else {
console.error('Tried to call a callback with invalid type: ' + type); console.error('Tried to call a callback with invalid type: ' + type);
@ -87,19 +92,22 @@ var JSTimersExecution = {
* This is called from the native side. We are passed an array of timerIDs, * This is called from the native side. We are passed an array of timerIDs,
* and * and
*/ */
callTimers: function(timerIDs) { callTimers(timerIDs) {
invariant(timerIDs.length !== 0, 'Probably shouldn\'t call "callTimers" with no timerIDs'); invariant(
timerIDs.length !== 0,
'Cannot call `callTimers` with an empty list of IDs.'
);
JSTimersExecution.errors = null; JSTimersExecution.errors = null;
timerIDs.forEach(JSTimersExecution.callTimer); timerIDs.forEach(JSTimersExecution.callTimer);
var errors = JSTimersExecution.errors; const errors = JSTimersExecution.errors;
if (errors) { if (errors) {
var errorCount = errors.length; const errorCount = errors.length;
if (errorCount > 1) { if (errorCount > 1) {
// Throw all the other errors in a setTimeout, which will throw each // Throw all the other errors in a setTimeout, which will throw each
// error one at a time // error one at a time
for (var ii = 1; ii < errorCount; ii++) { for (let ii = 1; ii < errorCount; ii++) {
require('JSTimers').setTimeout( require('JSTimers').setTimeout(
((error) => { throw error; }).bind(null, errors[ii]), ((error) => { throw error; }).bind(null, errors[ii]),
0 0
@ -114,18 +122,18 @@ var JSTimersExecution = {
* Performs a single pass over the enqueued immediates. Returns whether * Performs a single pass over the enqueued immediates. Returns whether
* more immediates are queued up (can be used as a condition a while loop). * more immediates are queued up (can be used as a condition a while loop).
*/ */
callImmediatesPass: function() { callImmediatesPass() {
Systrace.beginEvent('JSTimersExecution.callImmediatesPass()'); Systrace.beginEvent('JSTimersExecution.callImmediatesPass()');
// The main reason to extract a single pass is so that we can track // The main reason to extract a single pass is so that we can track
// in the system trace // in the system trace
if (JSTimersExecution.immediates.length > 0) { if (JSTimersExecution.immediates.length > 0) {
var passImmediates = JSTimersExecution.immediates.slice(); const passImmediates = JSTimersExecution.immediates.slice();
JSTimersExecution.immediates = []; JSTimersExecution.immediates = [];
// Use for loop rather than forEach as per @vjeux's advice // Use for loop rather than forEach as per @vjeux's advice
// https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051 // https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051
for (var i = 0; i < passImmediates.length; ++i) { for (let i = 0; i < passImmediates.length; ++i) {
JSTimersExecution.callTimer(passImmediates[i]); JSTimersExecution.callTimer(passImmediates[i]);
} }
} }
@ -139,7 +147,7 @@ var JSTimersExecution = {
* This is called after we execute any command we receive from native but * This is called after we execute any command we receive from native but
* before we hand control back to native. * before we hand control back to native.
*/ */
callImmediates: function() { callImmediates() {
JSTimersExecution.errors = null; JSTimersExecution.errors = null;
while (JSTimersExecution.callImmediatesPass()) {} while (JSTimersExecution.callImmediatesPass()) {}
if (JSTimersExecution.errors) { if (JSTimersExecution.errors) {
@ -152,7 +160,7 @@ var JSTimersExecution = {
/** /**
* Called from native (in development) when environment times are out-of-sync. * Called from native (in development) when environment times are out-of-sync.
*/ */
emitTimeDriftWarning: function(warningMessage) { emitTimeDriftWarning(warningMessage) {
if (hasEmittedTimeDriftWarning) { if (hasEmittedTimeDriftWarning) {
return; return;
} }
@ -160,7 +168,7 @@ var JSTimersExecution = {
console.warn(warningMessage); console.warn(warningMessage);
}, },
_clearIndex: function(i) { _clearIndex(i) {
JSTimersExecution.timerIDs[i] = null; JSTimersExecution.timerIDs[i] = null;
JSTimersExecution.callbacks[i] = null; JSTimersExecution.callbacks[i] = null;
JSTimersExecution.types[i] = null; JSTimersExecution.types[i] = null;