初窺React-9 (scheduleUpdateOnFiber方法-2)
阿新 • • 發佈:2021-07-13
//排程決策的邏輯在ensureRootIsScheduled 函式中, 任務優先順序在即將排程的時候去計算,程式碼在ensureRootIsScheduled函式中: function ensureRootIsScheduled(root, currentTime) { var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as // expired so we know to work on those next.markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. //通過呼叫getNextLanes去計算在本次更新中應該處理的這批lanes(nextLanes) //getNextLanes會呼叫getHighestPriorityLanes去計算任務優先順序。任務優先順序計算的原理是這樣:更新優先順序(update的lane), //它會被併入root.pendingLanes,root.pendingLanes經過getNextLanes處理後,挑出那些應該處理的lanes,傳入getHighestPriorityLanes,//根據nextLanes找出這些lanes的優先順序作為任務優先順序。 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); // This returns the priority level computed during the `getNextLanes` call. var newCallbackPriority = returnNextLanesPriority(); if (nextLanes === NoLanes) {// Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); root.callbackNode = null; root.callbackPriority = NoLanePriority; } return; } // Check if there's an existing task. We may be able to reuse it. if (existingCallbackNode !== null) { var existingCallbackPriority = root.callbackPriority; if (existingCallbackPriority === newCallbackPriority) { // The priority hasn't changed. We can reuse the existing task. Exit. return; } // The priority changed. Cancel the existing callback. We'll schedule a new // one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. var newCallbackNode; if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue newCallbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root)); } else { var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority); newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)); } root.callbackPriority = newCallbackPriority; root.callbackNode = newCallbackNode; }
function resetRenderTimer() { workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS; }
function flushSyncCallbackQueue() { if (immediateQueueCallbackNode !== null) { var node = immediateQueueCallbackNode; immediateQueueCallbackNode = null; Scheduler_cancelCallback(node); } flushSyncCallbackQueueImpl(); } function flushSyncCallbackQueueImpl() { if (!isFlushingSyncQueue && syncQueue !== null) { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; { try { var _isSync2 = true; var _queue = syncQueue; runWithPriority$1(ImmediatePriority$1, function () { for (; i < _queue.length; i++) { var callback = _queue[i]; do { callback = callback(_isSync2); } while (callback !== null); } }); syncQueue = null; } catch (error) { // If something throws, leave the remaining callbacks on the queue. if (syncQueue !== null) { syncQueue = syncQueue.slice(i + 1); } // Resume flushing in the next tick Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue); throw error; } finally { isFlushingSyncQueue = false; } } } }