MCPcopy
hub / github.com/facebook/react / trackUsedThenable

Function trackUsedThenable

packages/react-server/src/ReactFizzThenable.js:45–132  ·  view source on GitHub ↗
(
  thenableState: ThenableState,
  thenable: Thenable<T>,
  index: number,
)

Source from the content-addressed store, hash-verified

43}
44
45export function trackUsedThenable<T>(
46 thenableState: ThenableState,
47 thenable: Thenable<T>,
48 index: number,
49): T {
50 const previous = thenableState[index];
51 if (previous === undefined) {
52 thenableState.push(thenable);
53 } else {
54 if (previous !== thenable) {
55 // Reuse the previous thenable, and drop the new one. We can assume
56 // they represent the same value, because components are idempotent.
57
58 // Avoid an unhandled rejection errors for the Promises that we'll
59 // intentionally ignore.
60 thenable.then(noop, noop);
61 thenable = previous;
62 }
63 }
64
65 // We use an expando to track the status and result of a thenable so that we
66 // can synchronously unwrap the value. Think of this as an extension of the
67 // Promise API, or a custom interface that is a superset of Thenable.
68 //
69 // If the thenable doesn't have a status, set it to "pending" and attach
70 // a listener that will update its status and result when it resolves.
71 switch (thenable.status) {
72 case 'fulfilled': {
73 const fulfilledValue: T = thenable.value;
74 return fulfilledValue;
75 }
76 case 'rejected': {
77 const rejectedError = thenable.reason;
78 throw rejectedError;
79 }
80 default: {
81 if (typeof thenable.status === 'string') {
82 // Only instrument the thenable if the status if not defined. If
83 // it's defined, but an unknown value, assume it's been instrumented by
84 // some custom userspace implementation. We treat it as "pending".
85 // Attach a dummy listener, to ensure that any lazy initialization can
86 // happen. Flight lazily parses JSON when the value is actually awaited.
87 thenable.then(noop, noop);
88 } else {
89 const pendingThenable: PendingThenable<T> = (thenable: any);
90 pendingThenable.status = 'pending';
91 pendingThenable.then(
92 fulfilledValue => {
93 if (thenable.status === 'pending') {
94 const fulfilledThenable: FulfilledThenable<T> = (thenable: any);
95 fulfilledThenable.status = 'fulfilled';
96 fulfilledThenable.value = fulfilledValue;
97 }
98 },
99 (error: mixed) => {
100 if (thenable.status === 'pending') {
101 const rejectedThenable: RejectedThenable<T> = (thenable: any);
102 rejectedThenable.status = 'rejected';

Callers 1

unwrapThenableFunction · 0.90

Calls 2

pushMethod · 0.65
thenMethod · 0.65

Tested by

no test coverage detected