88 */
99
1010import type {
11- Wakeable ,
1211 Thenable ,
1312 PendingThenable ,
1413 FulfilledThenable ,
@@ -18,14 +17,8 @@ import type {
1817import ReactSharedInternals from 'shared/ReactSharedInternals' ;
1918const { ReactCurrentActQueue} = ReactSharedInternals ;
2019
21- let suspendedThenable : Thenable < mixed > | null = null ;
22- let adHocSuspendCount : number = 0 ;
23-
24- // TODO: Sparse arrays are bad for performance.
20+ let suspendedThenable : Thenable < any > | null = null ;
2521let usedThenables : Array < Thenable < any > | void > | null = null ;
26- let lastUsedThenable : Thenable < any > | null = null ;
27-
28- const MAX_AD_HOC_SUSPEND_COUNT = 50 ;
2922
3023export function isTrackingSuspendedThenable ( ) : boolean {
3124 return suspendedThenable !== null ;
@@ -39,22 +32,17 @@ export function suspendedThenableDidResolve(): boolean {
3932 return false ;
4033}
4134
42- export function trackSuspendedWakeable ( wakeable : Wakeable ) {
43- // If this wakeable isn't already a thenable, turn it into one now. Then,
44- // when we resume the work loop, we can check if its status is
45- // still pending.
46- // TODO: Get rid of the Wakeable type? It's superseded by UntrackedThenable.
47- const thenable : Thenable < mixed > = (wakeable: any);
35+ export function trackUsedThenable < T > ( thenable : Thenable < T > , index : number ) {
36+ if ( __DEV__ && ReactCurrentActQueue . current !== null ) {
37+ ReactCurrentActQueue . didUsePromise = true ;
38+ }
4839
49- if (thenable !== lastUsedThenable) {
50- // If this wakeable was not just `use`-d, it must be an ad hoc wakeable
51- // that was thrown by an older Suspense implementation. Keep a count of
52- // these so that we can detect an infinite ping loop.
53- // TODO: Once `use` throws an opaque signal instead of the actual thenable,
54- // a better way to count ad hoc suspends is whether an actual thenable
55- // is caught by the work loop.
56- adHocSuspendCount ++ ;
40+ if ( usedThenables === null ) {
41+ usedThenables = [ thenable ] ;
42+ } else {
43+ usedThenables [ index ] = thenable ;
5744 }
45+
5846 suspendedThenable = thenable ;
5947
6048 // We use an expando to track the status and result of a thenable so that we
@@ -105,34 +93,12 @@ export function trackSuspendedWakeable(wakeable: Wakeable) {
10593
10694export function resetWakeableStateAfterEachAttempt ( ) {
10795 suspendedThenable = null ;
108- adHocSuspendCount = 0 ;
109- lastUsedThenable = null ;
11096}
11197
11298export function resetThenableStateOnCompletion() {
11399 usedThenables = null ;
114100}
115101
116- export function throwIfInfinitePingLoopDetected() {
117- if ( adHocSuspendCount > MAX_AD_HOC_SUSPEND_COUNT ) {
118- // TODO: Guard against an infinite loop by throwing an error if the same
119- // component suspends too many times in a row. This should be thrown from
120- // the render phase so that it gets the component stack.
121- }
122- }
123-
124- export function trackUsedThenable< T > (thenable: Thenable< T > , index: number) {
125- if ( usedThenables === null ) {
126- usedThenables = [ ] ;
127- }
128- usedThenables[index] = thenable;
129- lastUsedThenable = thenable;
130-
131- if (__DEV__ && ReactCurrentActQueue . current !== null ) {
132- ReactCurrentActQueue . didUsePromise = true ;
133- }
134- }
135-
136102export function getPreviouslyUsedThenableAtIndex< T > (
137103 index: number,
138104): Thenable< T > | null {
0 commit comments