Skip to content

Commit 0a28b34

Browse files
Huxprofacebook-github-bot
authored andcommitted
Conditionalize Promise Polyfill for Hermes
Summary: On Hermes, RN can directly use the Promise from global w/o the need of polyfilling it. PromiseRejectionTrackingOptions are extracted to its own file so it can be shared by both codepaths and preserve the behaviors that it's only imported on dev. Some zero-overhead type gymnastics are used to flow-type it properly. Changelog: [General] - made promise polyfill conditionalized on Hermes Reviewed By: cpojer Differential Revision: D24068716 fbshipit-source-id: 3e0b1675493908324f27cc5b7300d8cc42a03acc
1 parent 3c154c8 commit 0a28b34

File tree

3 files changed

+74
-37
lines changed

3 files changed

+74
-37
lines changed

Libraries/Core/polyfillPromise.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,20 @@ const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
1919
* If you don't need these polyfills, don't use InitializeCore; just directly
2020
* require the modules you need from InitializeCore for setup.
2121
*/
22-
polyfillGlobal('Promise', () => require('../Promise'));
22+
23+
// If global.Promise is provided by Hermes, we are confident that it can provide
24+
// all the methods needed by React Native, so we can directly use it.
25+
if (global?.HermesInternal?.hasPromise?.()) {
26+
const HermesPromise = global.Promise;
27+
28+
if (__DEV__) {
29+
if (typeof HermesPromise !== 'function') {
30+
console.error('HermesPromise does not exist');
31+
}
32+
global.HermesInternal.enablePromiseRejectionTracker(
33+
require('../promiseRejectionTrackingOptions').default,
34+
);
35+
}
36+
} else {
37+
polyfillGlobal('Promise', () => require('../Promise'));
38+
}

Libraries/Promise.js

+3-36
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,9 @@ require('promise/setimmediate/done');
1616
require('promise/setimmediate/finally');
1717

1818
if (__DEV__) {
19-
require('promise/setimmediate/rejection-tracking').enable({
20-
allRejections: true,
21-
onUnhandled: (id, rejection = {}) => {
22-
let message: string;
23-
let stack: ?string;
24-
25-
const stringValue = Object.prototype.toString.call(rejection);
26-
if (stringValue === '[object Error]') {
27-
message = Error.prototype.toString.call(rejection);
28-
const error: Error = (rejection: $FlowFixMe);
29-
stack = error.stack;
30-
} else {
31-
try {
32-
message = require('pretty-format')(rejection);
33-
} catch {
34-
message =
35-
typeof rejection === 'string'
36-
? rejection
37-
: JSON.stringify((rejection: $FlowFixMe));
38-
}
39-
}
40-
41-
const warning =
42-
`Possible Unhandled Promise Rejection (id: ${id}):\n` +
43-
`${message ?? ''}\n` +
44-
(stack == null ? '' : stack);
45-
console.warn(warning);
46-
},
47-
onHandled: id => {
48-
const warning =
49-
`Promise Rejection Handled (id: ${id})\n` +
50-
'This means you can ignore any previous messages of the form ' +
51-
`"Possible Unhandled Promise Rejection (id: ${id}):"`;
52-
console.warn(warning);
53-
},
54-
});
19+
require('promise/setimmediate/rejection-tracking').enable(
20+
require('./promiseRejectionTrackingOptions').default,
21+
);
5522
}
5623

5724
module.exports = Promise;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @flow strict
9+
*/
10+
11+
'use strict';
12+
13+
import typeof {enable} from 'promise/setimmediate/rejection-tracking';
14+
15+
type ExtractOptionsType = <P>((options?: ?P) => void) => P;
16+
17+
let rejectionTrackingOptions: $Call<ExtractOptionsType, enable> = {
18+
allRejections: true,
19+
onUnhandled: (id, rejection = {}) => {
20+
let message: string;
21+
let stack: ?string;
22+
23+
const stringValue = Object.prototype.toString.call(rejection);
24+
if (stringValue === '[object Error]') {
25+
message = Error.prototype.toString.call(rejection);
26+
const error: Error = (rejection: $FlowFixMe);
27+
stack = error.stack;
28+
} else {
29+
try {
30+
message = require('pretty-format')(rejection);
31+
} catch {
32+
message =
33+
typeof rejection === 'string'
34+
? rejection
35+
: JSON.stringify((rejection: $FlowFixMe));
36+
}
37+
}
38+
39+
const warning =
40+
`Possible Unhandled Promise Rejection (id: ${id}):\n` +
41+
`${message ?? ''}\n` +
42+
(stack == null ? '' : stack);
43+
console.warn(warning);
44+
},
45+
onHandled: id => {
46+
const warning =
47+
`Promise Rejection Handled (id: ${id})\n` +
48+
'This means you can ignore any previous messages of the form ' +
49+
`"Possible Unhandled Promise Rejection (id: ${id}):"`;
50+
console.warn(warning);
51+
},
52+
};
53+
54+
export default rejectionTrackingOptions;

0 commit comments

Comments
 (0)