Skip to content

Commit 9f08277

Browse files
committed
Pass value to right callback
1 parent bed8fb4 commit 9f08277

File tree

5 files changed

+83
-28
lines changed

5 files changed

+83
-28
lines changed

packages/react-devtools-shared/src/devtools/views/ErrorBoundary/cache.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,30 @@ export function findGitHubIssue(errorMessage: string): GitHubIssue | null {
5757
let record = map.get(errorMessage);
5858

5959
if (!record) {
60-
const callbacks = new Set<() => mixed>();
60+
const callbacks = new Set<(value: any) => mixed>();
61+
const rejectCallbacks = new Set<(reason: mixed) => mixed>();
6162
const thenable: Thenable<GitHubIssue> = {
6263
status: 'pending',
6364
value: null,
6465
reason: null,
6566
then(callback: (value: any) => mixed, reject: (error: mixed) => mixed) {
6667
callbacks.add(callback);
68+
rejectCallbacks.add(reject);
6769
},
6870

6971
// Optional property used by Timeline:
7072
displayName: `Searching GitHub issues for error "${errorMessage}"`,
7173
};
7274
const wake = () => {
7375
// This assumes they won't throw.
74-
callbacks.forEach(callback => callback());
76+
callbacks.forEach(callback => callback((thenable: any).value));
77+
callbacks.clear();
78+
rejectCallbacks.clear();
79+
};
80+
const wakeRejections = () => {
81+
// This assumes they won't throw.
82+
rejectCallbacks.forEach(callback => callback((thenable: any).reason));
83+
rejectCallbacks.clear();
7584
callbacks.clear();
7685
};
7786
record = thenable;
@@ -89,21 +98,20 @@ export function findGitHubIssue(errorMessage: string): GitHubIssue | null {
8998
(thenable: any);
9099
fulfilledThenable.status = 'fulfilled';
91100
fulfilledThenable.value = maybeItem;
101+
wake();
92102
} else {
93103
const notFoundThenable: RejectedThenable<GitHubIssue> =
94104
(thenable: any);
95105
notFoundThenable.status = 'rejected';
96106
notFoundThenable.reason = null;
107+
wakeRejections();
97108
}
98-
99-
wake();
100109
})
101110
.catch(error => {
102111
const rejectedThenable: RejectedThenable<GitHubIssue> = (thenable: any);
103112
rejectedThenable.status = 'rejected';
104113
rejectedThenable.reason = null;
105-
106-
wake();
114+
wakeRejections();
107115
});
108116

109117
// Only wait a little while for GitHub results before showing a fallback.
@@ -113,8 +121,7 @@ export function findGitHubIssue(errorMessage: string): GitHubIssue | null {
113121
const timedoutThenable: RejectedThenable<GitHubIssue> = (thenable: any);
114122
timedoutThenable.status = 'rejected';
115123
timedoutThenable.reason = null;
116-
117-
wake();
124+
wakeRejections();
118125
}, API_TIMEOUT);
119126

120127
map.set(errorMessage, record);

packages/react-devtools-shared/src/dynamicImportCache.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,15 @@ export function loadModule(moduleLoaderFunction: ModuleLoaderFunction): Module {
5858
}
5959

6060
if (!record) {
61-
const callbacks = new Set<() => mixed>();
61+
const callbacks = new Set<(value: any) => mixed>();
62+
const rejectCallbacks = new Set<(reason: mixed) => mixed>();
6263
const thenable: Thenable<Module> = {
6364
status: 'pending',
6465
value: null,
6566
reason: null,
6667
then(callback: (value: any) => mixed, reject: (error: mixed) => mixed) {
6768
callbacks.add(callback);
69+
rejectCallbacks.add(reject);
6870
},
6971

7072
// Optional property used by Timeline:
@@ -80,6 +82,18 @@ export function loadModule(moduleLoaderFunction: ModuleLoaderFunction): Module {
8082
// This assumes they won't throw.
8183
callbacks.forEach(callback => callback());
8284
callbacks.clear();
85+
rejectCallbacks.clear();
86+
};
87+
const wakeRejections = () => {
88+
if (timeoutID) {
89+
clearTimeout(timeoutID);
90+
timeoutID = null;
91+
}
92+
93+
// This assumes they won't throw.
94+
rejectCallbacks.forEach(callback => callback((thenable: any).reason));
95+
rejectCallbacks.clear();
96+
callbacks.clear();
8397
};
8498

8599
record = thenable;
@@ -121,7 +135,7 @@ export function loadModule(moduleLoaderFunction: ModuleLoaderFunction): Module {
121135
rejectedThenable.status = 'rejected';
122136
rejectedThenable.reason = error;
123137

124-
wake();
138+
wakeRejections();
125139
},
126140
);
127141

@@ -141,7 +155,7 @@ export function loadModule(moduleLoaderFunction: ModuleLoaderFunction): Module {
141155
rejectedThenable.status = 'rejected';
142156
rejectedThenable.reason = null;
143157

144-
wake();
158+
wakeRejections();
145159
}, TIMEOUT);
146160

147161
moduleLoaderFunctionToModuleMap.set(moduleLoaderFunction, record);

packages/react-devtools-shared/src/hookNamesCache.js

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function readRecord<T>(record: Thenable<T>): T | null {
3434
try {
3535
return React.use(record);
3636
} catch (x) {
37-
if (x === null) {
37+
if (record.status === 'rejected') {
3838
return null;
3939
}
4040
throw x;
@@ -88,13 +88,15 @@ export function loadHookNames(
8888
}
8989

9090
if (!record) {
91-
const callbacks = new Set<() => mixed>();
91+
const callbacks = new Set<(value: any) => mixed>();
92+
const rejectCallbacks = new Set<(reason: mixed) => mixed>();
9293
const thenable: Thenable<HookNames> = {
9394
status: 'pending',
9495
value: null,
9596
reason: null,
9697
then(callback: (value: any) => mixed, reject: (error: mixed) => mixed) {
9798
callbacks.add(callback);
99+
rejectCallbacks.add(reject);
98100
},
99101

100102
// Optional property used by Timeline:
@@ -113,7 +115,18 @@ export function loadHookNames(
113115
}
114116

115117
// This assumes they won't throw.
116-
callbacks.forEach(callback => callback());
118+
callbacks.forEach(callback => callback((thenable: any).value));
119+
callbacks.clear();
120+
rejectCallbacks.clear();
121+
};
122+
const wakeRejections = () => {
123+
if (timeoutID) {
124+
clearTimeout(timeoutID);
125+
timeoutID = null;
126+
}
127+
// This assumes they won't throw.
128+
rejectCallbacks.forEach(callback => callback((thenable: any).reason));
129+
rejectCallbacks.clear();
117130
callbacks.clear();
118131
};
119132

@@ -148,17 +161,20 @@ export function loadHookNames(
148161
(thenable: any);
149162
fulfilledThenable.status = 'fulfilled';
150163
fulfilledThenable.value = hookNames;
164+
status = 'success';
165+
resolvedHookNames = hookNames;
166+
done();
167+
wake();
151168
} else {
152169
const notFoundThenable: RejectedThenable<HookNames> =
153170
(thenable: any);
154171
notFoundThenable.status = 'rejected';
155172
notFoundThenable.reason = null;
173+
status = 'error';
174+
resolvedHookNames = hookNames;
175+
done();
176+
wakeRejections();
156177
}
157-
158-
status = 'success';
159-
resolvedHookNames = hookNames;
160-
done();
161-
wake();
162178
},
163179
function onError(error) {
164180
if (didTimeout) {
@@ -178,7 +194,7 @@ export function loadHookNames(
178194

179195
status = 'error';
180196
done();
181-
wake();
197+
wakeRejections();
182198
},
183199
);
184200

@@ -198,7 +214,7 @@ export function loadHookNames(
198214

199215
status = 'timeout';
200216
done();
201-
wake();
217+
wakeRejections();
202218
}, TIMEOUT);
203219
},
204220
handleLoadComplete,

packages/react-devtools-shared/src/inspectedElementCache.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,15 @@ export function inspectElement(
8383
const map = getRecordMap();
8484
let record = map.get(element);
8585
if (!record) {
86-
const callbacks = new Set<() => mixed>();
86+
const callbacks = new Set<(value: any) => mixed>();
87+
const rejectCallbacks = new Set<(reason: mixed) => mixed>();
8788
const thenable: Thenable<InspectedElementFrontend> = {
8889
status: 'pending',
8990
value: null,
9091
reason: null,
9192
then(callback: (value: any) => mixed, reject: (error: mixed) => mixed) {
9293
callbacks.add(callback);
94+
rejectCallbacks.add(reject);
9395
},
9496

9597
// Optional property used by Timeline:
@@ -98,7 +100,14 @@ export function inspectElement(
98100

99101
const wake = () => {
100102
// This assumes they won't throw.
101-
callbacks.forEach(callback => callback());
103+
callbacks.forEach(callback => callback((thenable: any).value));
104+
callbacks.clear();
105+
rejectCallbacks.clear();
106+
};
107+
const wakeRejections = () => {
108+
// This assumes they won't throw.
109+
rejectCallbacks.forEach(callback => callback((thenable: any).reason));
110+
rejectCallbacks.clear();
102111
callbacks.clear();
103112
};
104113
record = thenable;
@@ -137,7 +146,7 @@ export function inspectElement(
137146
rejectedThenable.status = 'rejected';
138147
rejectedThenable.reason = error;
139148

140-
wake();
149+
wakeRejections();
141150
},
142151
);
143152

packages/react-devtools-timeline/src/timelineCache.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ export function importFile(file: File): TimelineData | Error {
5151
let record = fileNameToProfilerDataMap.get(fileName);
5252

5353
if (!record) {
54-
const callbacks = new Set<() => mixed>();
54+
const callbacks = new Set<(value: any) => mixed>();
55+
const rejectCallbacks = new Set<(reason: mixed) => mixed>();
5556
const thenable: Thenable<TimelineData> = {
5657
status: 'pending',
5758
value: null,
5859
reason: null,
5960
then(callback: (value: any) => mixed, reject: (error: mixed) => mixed) {
6061
callbacks.add(callback);
62+
rejectCallbacks.add(reject);
6163
},
6264

6365
// Optional property used by Timeline:
@@ -66,7 +68,14 @@ export function importFile(file: File): TimelineData | Error {
6668

6769
const wake = () => {
6870
// This assumes they won't throw.
69-
callbacks.forEach(callback => callback());
71+
callbacks.forEach(callback => callback((thenable: any).value));
72+
callbacks.clear();
73+
rejectCallbacks.clear();
74+
};
75+
const wakeRejections = () => {
76+
// This assumes they won't throw.
77+
rejectCallbacks.forEach(callback => callback((thenable: any).reason));
78+
rejectCallbacks.clear();
7079
callbacks.clear();
7180
};
7281

@@ -79,17 +88,17 @@ export function importFile(file: File): TimelineData | Error {
7988
(thenable: any);
8089
fulfilledThenable.status = 'fulfilled';
8190
fulfilledThenable.value = data.processedData;
91+
wake();
8292
break;
8393
case 'INVALID_PROFILE_ERROR':
8494
case 'UNEXPECTED_ERROR':
8595
const rejectedThenable: RejectedThenable<TimelineData> =
8696
(thenable: any);
8797
rejectedThenable.status = 'rejected';
8898
rejectedThenable.reason = data.error;
99+
wakeRejections();
89100
break;
90101
}
91-
92-
wake();
93102
});
94103

95104
fileNameToProfilerDataMap.set(fileName, record);

0 commit comments

Comments
 (0)