3320
request: Request,
3321
task: ReplayTask,
3322
thenableState: ThenableState | null,
3323
- x: Wakeable,
3324
-): void {
3325
- const newTask = createReplayTask(
3323
+): ReplayTask {
3324
+ return createReplayTask(
3325
request,
3326
thenableState,
3327
task.replay,
3339
!disableLegacyContext ? task.legacyContext : emptyContextObject,
3340
__DEV__ && enableOwnerStacks ? task.debugTask : null,
3341
);
3343
-
3344
- const ping = newTask.ping;
3345
- x.then(ping, ping);
3342
}
3343
3344
function spawnNewSuspendedRenderTask(
3345
request: Request,
3346
task: RenderTask,
3347
thenableState: ThenableState | null,
3352
- x: Wakeable,
3353
-): void {
3348
+): RenderTask {
3349
// Something suspended, we'll need to create a new segment and resolve it later.
3350
const segment = task.blockedSegment;
3351
const insertionIndex = segment.chunks.length;
3362
segment.children.push(newSegment);
3363
// Reset lastPushedText for current Segment since the new Segment "consumed" it
3364
segment.lastPushedText = false;
3370
- const newTask = createRenderTask(
3365
+ return createRenderTask(
3366
request,
3367
thenableState,
3368
task.node,
3380
!disableLegacyContext ? task.legacyContext : emptyContextObject,
3381
__DEV__ && enableOwnerStacks ? task.debugTask : null,
3382
);
3388
-
3389
- const ping = newTask.ping;
3390
- x.then(ping, ping);
3383
}
3384
3385
// This is a non-destructive form of rendering a node. If it suspends it spawns
3428
if (typeof x.then === 'function') {
3429
const wakeable: Wakeable = (x: any);
3430
const thenableState = getThenableStateAfterSuspending();
3439
- spawnNewSuspendedReplayTask(
3431
+ const newTask = spawnNewSuspendedReplayTask(
3432
+ request,
3433
+ // $FlowFixMe: Refined.
3434
+ task,
3435
+ thenableState,
3436
+ );
3437
+ const ping = newTask.ping;
3438
+ wakeable.then(ping, ping);
3439
+
3440
+ // Restore the context. We assume that this will be restored by the inner
3441
+ // functions in case nothing throws so we don't use "finally" here.
3442
+ task.formatContext = previousFormatContext;
3443
+ if (!disableLegacyContext) {
3444
+ task.legacyContext = previousLegacyContext;
3445
+ }
3446
+ task.context = previousContext;
3447
+ task.keyPath = previousKeyPath;
3448
+ task.treeContext = previousTreeContext;
3449
+ task.componentStack = previousComponentStack;
3450
+ if (__DEV__ && enableOwnerStacks) {
3451
+ task.debugTask = previousDebugTask;
3452
+ }
3453
+ // Restore all active ReactContexts to what they were before.
3454
+ switchContext(previousContext);
3455
+ return;
3456
+ }
3457
+ if (x.message === 'Maximum call stack size exceeded') {
3458
+ // This was a stack overflow. We do a lot of recursion in React by default for
3459
+ // performance but it can lead to stack overflows in extremely deep trees.
3460
+ // We do have the ability to create a trampoile if this happens which makes
3461
+ // this kind of zero-cost.
3462
+ const thenableState = getThenableStateAfterSuspending();
3463
+ const newTask = spawnNewSuspendedReplayTask(
3464
request,
3465
// $FlowFixMe: Refined.
3466
task,
3467
thenableState,
3444
- wakeable,
3468
);
3469
3470
+ // Immediately schedule the task for retrying.
3471
+ request.pingedTasks.push(newTask);
3472
+
3473
// Restore the context. We assume that this will be restored by the inner
3474
// functions in case nothing throws so we don't use "finally" here.
3475
task.formatContext = previousFormatContext;
3519
if (typeof x.then === 'function') {
3520
const wakeable: Wakeable = (x: any);
3521
const thenableState = getThenableStateAfterSuspending();
3496
- spawnNewSuspendedRenderTask(
3522
+ const newTask = spawnNewSuspendedRenderTask(
3523
request,
3524
// $FlowFixMe: Refined.
3525
task,
3526
thenableState,
3501
- wakeable,
3527
);
3528
+ const ping = newTask.ping;
3529
+ wakeable.then(ping, ping);
3530
3531
// Restore the context. We assume that this will be restored by the inner
3532
// functions in case nothing throws so we don't use "finally" here.
3567
);
3568
trackPostpone(request, trackedPostpones, task, postponedSegment);
3569
3570
+ // Restore the context. We assume that this will be restored by the inner
3571
+ // functions in case nothing throws so we don't use "finally" here.
3572
+ task.formatContext = previousFormatContext;
3573
+ if (!disableLegacyContext) {
3574
+ task.legacyContext = previousLegacyContext;
3575
+ }
3576
+ task.context = previousContext;
3577
+ task.keyPath = previousKeyPath;
3578
+ task.treeContext = previousTreeContext;
3579
+ task.componentStack = previousComponentStack;
3580
+ if (__DEV__ && enableOwnerStacks) {
3581
+ task.debugTask = previousDebugTask;
3582
+ }
3583
+ // Restore all active ReactContexts to what they were before.
3584
+ switchContext(previousContext);
3585
+ return;
3586
+ }
3587
+ if (x.message === 'Maximum call stack size exceeded') {
3588
+ // This was a stack overflow. We do a lot of recursion in React by default for
3589
+ // performance but it can lead to stack overflows in extremely deep trees.
3590
+ // We do have the ability to create a trampoile if this happens which makes
3591
+ // this kind of zero-cost.
3592
+ const thenableState = getThenableStateAfterSuspending();
3593
+ const newTask = spawnNewSuspendedRenderTask(
3594
+ request,
3595
+ // $FlowFixMe: Refined.
3596
+ task,
3597
+ thenableState,
3598
+ );
3599
+
3600
+ // Immediately schedule the task for retrying.
3601
+ request.pingedTasks.push(newTask);
3602
+
3603
// Restore the context. We assume that this will be restored by the inner
3604
// functions in case nothing throws so we don't use "finally" here.
3605
task.formatContext = previousFormatContext;