( root: FiberRoot, wakeable: Wakeable, pingedLanes: Lanes, )
| 4775 | } |
| 4776 | |
| 4777 | function pingSuspendedRoot( |
| 4778 | root: FiberRoot, |
| 4779 | wakeable: Wakeable, |
| 4780 | pingedLanes: Lanes, |
| 4781 | ) { |
| 4782 | const pingCache = root.pingCache; |
| 4783 | if (pingCache !== null) { |
| 4784 | // The wakeable resolved, so we no longer need to memoize, because it will |
| 4785 | // never be thrown again. |
| 4786 | pingCache.delete(wakeable); |
| 4787 | } |
| 4788 | |
| 4789 | markRootPinged(root, pingedLanes); |
| 4790 | |
| 4791 | if (enableProfilerTimer && enableComponentPerformanceTrack) { |
| 4792 | startPingTimerByLanes(pingedLanes); |
| 4793 | } |
| 4794 | |
| 4795 | warnIfSuspenseResolutionNotWrappedWithActDEV(root); |
| 4796 | |
| 4797 | if ( |
| 4798 | workInProgressRoot === root && |
| 4799 | isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes) |
| 4800 | ) { |
| 4801 | // Received a ping at the same priority level at which we're currently |
| 4802 | // rendering. We might want to restart this render. This should mirror |
| 4803 | // the logic of whether or not a root suspends once it completes. |
| 4804 | // TODO: If we're rendering sync either due to Sync, Batched or expired, |
| 4805 | // we should probably never restart. |
| 4806 | // TODO: Attach different listeners depending on whether the listener was |
| 4807 | // attached during prerendering. Prerender pings should not interrupt |
| 4808 | // normal renders. |
| 4809 | |
| 4810 | // If we're suspended with delay, or if it's a retry, we'll always suspend |
| 4811 | // so we can always restart. |
| 4812 | if ( |
| 4813 | workInProgressRootExitStatus === RootSuspendedWithDelay || |
| 4814 | (workInProgressRootExitStatus === RootSuspended && |
| 4815 | includesOnlyRetries(workInProgressRootRenderLanes) && |
| 4816 | now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) |
| 4817 | ) { |
| 4818 | // Force a restart from the root by unwinding the stack. Unless this is |
| 4819 | // being called from the render phase, because that would cause a crash. |
| 4820 | if ((executionContext & RenderContext) === NoContext) { |
| 4821 | prepareFreshStack(root, NoLanes); |
| 4822 | } else { |
| 4823 | // TODO: If this does happen during the render phase, we should throw |
| 4824 | // the special internal exception that we use to interrupt the stack for |
| 4825 | // selective hydration. That was temporarily reverted but we once we add |
| 4826 | // it back we can use it here. |
| 4827 | } |
| 4828 | } else { |
| 4829 | // Even though we can't restart right now, we might get an |
| 4830 | // opportunity later. So we mark this render as having a ping. |
| 4831 | workInProgressRootPingedLanes = mergeLanes( |
| 4832 | workInProgressRootPingedLanes, |
| 4833 | pingedLanes, |
| 4834 | ); |
nothing calls this directly
no test coverage detected