Skip to content

Commit 0dca9c2

Browse files
authored
[Flight] Use the Promise of the first await even if that is cut off (facebook#33948)
We need a "value" to represent the I/O that was loaded. We don't normally actually use the Promise at the callsite that started the I/O because that's usually deep inside internals. Instead we override the value of the I/O entry with the Promise that was first awaited in user space. This means that you could potentially have different values depending on if multiple things await the same I/O. We just take one of them. (Maybe we should actually just write the first user space awaited Promise as the I/O entry? This might instead have other implications like less deduping.) When you pass a Promise forward, we may skip the awaits that happened in earlier components because they're not part of the currently rendering component. That's mainly for the stack and time stamps though. The value is still probably conceptually the best value because it represents the I/O value as far user space is concerned. This writes the I/O early with the first await we find in user space even if we're not going to use that particular await for the stack.
1 parent b9af140 commit 0dca9c2

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,21 @@ function visitAsyncNode(
23272327
// then this gets I/O ignored, which is what we want because it means it was likely
23282328
// just part of a previous component's rendering.
23292329
match = ioNode;
2330+
if (
2331+
node.stack !== null &&
2332+
isAwaitInUserspace(request, node.stack)
2333+
) {
2334+
// This await happened earlier but it was done in user space. This is the first time
2335+
// that user space saw the value of the I/O. We know we'll emit the I/O eventually
2336+
// but if we do it now we can override the promise value of the I/O entry to the
2337+
// one observed by this await which will be a better value than the internals of
2338+
// the I/O entry. If it's still alive that is.
2339+
const promise =
2340+
awaited.promise === null ? undefined : awaited.promise.deref();
2341+
if (promise !== undefined) {
2342+
serializeIONode(request, ioNode, awaited.promise);
2343+
}
2344+
}
23302345
} else {
23312346
if (
23322347
node.stack === null ||

packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
491491
],
492492
"start": 0,
493493
"value": {
494-
"status": "halted",
494+
"value": undefined,
495495
},
496496
},
497497
"env": "Server",

0 commit comments

Comments
 (0)