1. 程式人生 > 其它 >初窺React-9 (scheduleUpdateOnFiber方法-2)

初窺React-9 (scheduleUpdateOnFiber方法-2)

//排程決策的邏輯在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;
        }
      }
    }
  }