Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions packages/react-server/src/ReactFlightServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2347,7 +2347,8 @@ function visitAsyncNodeImpl(
// The technique for debugging the effects of uncached data on the render is to simply uncache it.
return null;
}
let previousIONode = null;

let previousIONode: void | null | PromiseNode | IONode = null;
// First visit anything that blocked this sequence to start in the first place.
if (node.previous !== null) {
previousIONode = visitAsyncNode(
Expand All @@ -2363,12 +2364,20 @@ function visitAsyncNodeImpl(
return undefined;
}
}

// `found` represents the return value of the following switch statement.
// We can't use multiple `return` statements in the switch statement
// since that prevents Closure compiler from inlining `visitAsyncImpl`
// thus doubling the call stack size.
let found: void | null | PromiseNode | IONode;
switch (node.tag) {
case IO_NODE: {
return node;
found = node;
break;
}
case UNRESOLVED_PROMISE_NODE: {
return previousIONode;
found = previousIONode;
break;
}
case PROMISE_NODE: {
const awaited = node.awaited;
Expand All @@ -2379,7 +2388,8 @@ function visitAsyncNodeImpl(
if (ioNode === undefined) {
// Undefined is used as a signal that we found a suitable aborted node and we don't have to find
// further aborted nodes.
return undefined;
found = undefined;
break;
} else if (ioNode !== null) {
// This Promise was blocked on I/O. That's a signal that this Promise is interesting to log.
// We don't log it yet though. We return it to be logged by the point where it's awaited.
Expand Down Expand Up @@ -2436,10 +2446,12 @@ function visitAsyncNodeImpl(
forwardDebugInfo(request, task, debugInfo);
}
}
return match;
found = match;
break;
}
case UNRESOLVED_AWAIT_NODE: {
return previousIONode;
found = previousIONode;
break;
}
case AWAIT_NODE: {
const awaited = node.awaited;
Expand All @@ -2449,7 +2461,8 @@ function visitAsyncNodeImpl(
if (ioNode === undefined) {
// Undefined is used as a signal that we found a suitable aborted node and we don't have to find
// further aborted nodes.
return undefined;
found = undefined;
break;
} else if (ioNode !== null) {
const startTime: number = node.start;
const endTime: number = node.end;
Expand Down Expand Up @@ -2545,13 +2558,15 @@ function visitAsyncNodeImpl(
forwardDebugInfo(request, task, debugInfo);
}
}
return match;
found = match;
break;
}
default: {
// eslint-disable-next-line react-internal/prod-error-codes
throw new Error('Unknown AsyncSequence tag. This is a bug in React.');
}
}
return found;
}

function emitAsyncSequence(
Expand Down
Loading