Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions packages/react/src/ReactLazy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';

import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';

import noop from 'shared/noop';

const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
Expand Down Expand Up @@ -67,12 +69,20 @@ export type LazyComponent<T, P> = {

function lazyInitializer<T>(payload: Payload<T>): T {
if (payload._status === Uninitialized) {
let resolveDebugValue: (void | T) => void = (null: any);
let rejectDebugValue: mixed => void = (null: any);
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Mark when we first kicked off the lazy request.
// $FlowFixMe[cannot-write]
ioInfo.start = ioInfo.end = performance.now();
// Stash a Promise for introspection of the value later.
// $FlowFixMe[cannot-write]
ioInfo.value = new Promise((resolve, reject) => {
resolveDebugValue = resolve;
rejectDebugValue = reject;
});
}
}
const ctor = payload._result;
Expand All @@ -92,12 +102,20 @@ function lazyInitializer<T>(payload: Payload<T>): T {
const resolved: ResolvedPayload<T> = (payload: any);
resolved._status = Resolved;
resolved._result = moduleObject;
if (__DEV__) {
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Mark the end time of when we resolved.
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Surface the default export as the resolved "value" for debug purposes.
const debugValue =
moduleObject == null ? undefined : moduleObject.default;
resolveDebugValue(debugValue);
// $FlowFixMe
ioInfo.value.status = 'fulfilled';
// $FlowFixMe
ioInfo.value.value = debugValue;
Comment on lines +111 to +118
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block isn't gated on enableAsyncDebugInfo but resolveDebugValue is only callable with enableAsyncDebugInfo. enableAsyncDebugInfo isn't enabled everywhere at the moment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is implied via payload._ioInfo but still nice for DCE and readability to gate it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The whole block should've been gated before just like the reject.

}
// Make the thenable introspectable
if (thenable.status === undefined) {
Expand All @@ -124,6 +142,14 @@ function lazyInitializer<T>(payload: Payload<T>): T {
// Mark the end time of when we rejected.
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Hide unhandled rejections.
// $FlowFixMe
ioInfo.value.then(noop, noop);
rejectDebugValue(error);
// $FlowFixMe
ioInfo.value.status = 'rejected';
// $FlowFixMe
ioInfo.value.reason = error;
}
// Make the thenable introspectable
if (thenable.status === undefined) {
Expand All @@ -139,9 +165,6 @@ function lazyInitializer<T>(payload: Payload<T>): T {
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Stash the thenable for introspection of the value later.
// $FlowFixMe[cannot-write]
ioInfo.value = thenable;
const displayName = thenable.displayName;
if (typeof displayName === 'string') {
// $FlowFixMe[cannot-write]
Expand Down
Loading