main
js 52 lines 1.44 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and 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 * @flow
8 */
9
10 import type {AsyncDispatcher} from 'react-reconciler/src/ReactInternalTypes';
11 import ReactSharedInternals from 'shared/ReactSharedInternals';
12
13 export function waitForSuspense<T>(fn: () => T): Promise<T> {
14 const cache: Map<Function, mixed> = new Map();
15 const testDispatcher: AsyncDispatcher = {
16 getCacheForType<R>(resourceType: () => R): R {
17 let entry: R | void = cache.get(resourceType) as any;
18 if (entry === undefined) {
19 entry = resourceType();
20 // TODO: Warn if undefined?
21 cache.set(resourceType, entry);
22 }
23 return entry;
24 },
25 cacheSignal(): null {
26 return null;
27 },
28 getOwner(): null {
29 return null;
30 },
31 };
32 // Not using async/await because we don't compile it.
33 return new Promise((resolve, reject) => {
34 function retry() {
35 const prevDispatcher = ReactSharedInternals.A;
36 ReactSharedInternals.A = testDispatcher;
37 try {
38 const result = fn();
39 resolve(result);
40 } catch (thrownValue) {
41 if (typeof thrownValue.then === 'function') {
42 thrownValue.then(retry, retry);
43 } else {
44 reject(thrownValue);
45 }
46 } finally {
47 ReactSharedInternals.A = prevDispatcher;
48 }
49 }
50 retry();
51 });
52 }