mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
[Fiber] Assign implicit debug info to used thenables (#34146)
Similar to #34137 but for Promises. This lets us pick up the debug info from a raw Promise as a child which is not covered by `_debugThenables`. Currently ChildFiber doesn't stash its thenables so we can't pick them up from devtools after the fact without some debug info added to the parent. It also lets us track some approximate start/end time of use():ed promises based on the first time we saw this particular Promise.
This commit is contained in:
committed by
GitHub
parent
34ce3acafd
commit
53d07944df
@@ -12,6 +12,7 @@ import type {
|
||||
PendingThenable,
|
||||
FulfilledThenable,
|
||||
RejectedThenable,
|
||||
ReactIOInfo,
|
||||
} from 'shared/ReactTypes';
|
||||
|
||||
import type {LazyComponent as LazyComponentType} from 'react/src/ReactLazy';
|
||||
@@ -22,6 +23,8 @@ import {getWorkInProgressRoot} from './ReactFiberWorkLoop';
|
||||
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
|
||||
import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import noop from 'shared/noop';
|
||||
|
||||
opaque type ThenableStateDev = {
|
||||
@@ -154,6 +157,33 @@ export function trackUsedThenable<T>(
|
||||
}
|
||||
}
|
||||
|
||||
if (__DEV__ && enableAsyncDebugInfo && thenable._debugInfo === undefined) {
|
||||
// In DEV mode if the thenable that we observed had no debug info, then we add
|
||||
// an inferred debug info so that we're able to track its potential I/O uniquely.
|
||||
// We don't know the real start time since the I/O could have started much
|
||||
// earlier and this could even be a cached Promise. Could be misleading.
|
||||
const startTime = performance.now();
|
||||
const displayName = thenable.displayName;
|
||||
const ioInfo: ReactIOInfo = {
|
||||
name: typeof displayName === 'string' ? displayName : 'Promise',
|
||||
start: startTime,
|
||||
end: startTime,
|
||||
value: (thenable: any),
|
||||
// We don't know the requesting owner nor stack.
|
||||
};
|
||||
// We can infer the await owner/stack lazily from where this promise ends up
|
||||
// used. It can be used in more than one place so we can't assign it here.
|
||||
thenable._debugInfo = [{awaited: ioInfo}];
|
||||
// Track when we resolved the Promise as the approximate end time.
|
||||
if (thenable.status !== 'fulfilled' && thenable.status !== 'rejected') {
|
||||
const trackEndTime = () => {
|
||||
// $FlowFixMe[cannot-write]
|
||||
ioInfo.end = performance.now();
|
||||
};
|
||||
thenable.then(trackEndTime, trackEndTime);
|
||||
}
|
||||
}
|
||||
|
||||
// We use an expando to track the status and result of a thenable so that we
|
||||
// can synchronously unwrap the value. Think of this as an extension of the
|
||||
// Promise API, or a custom interface that is a superset of Thenable.
|
||||
|
||||
Reference in New Issue
Block a user