// 这个函数是将ms转换为expiration time // 1单位的expiration time表示10ms functionmsToExpirationTime(ms: number): ExpirationTime{ // Always add an offset so that we don't clash with the magic number for NoWork. // 这里是怕出现结果为零的情况 // 按位或是舍弃小数取整 return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); }
functionrequestCurrentTimeForUpdate() { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { // We're inside React, so it's fine to read the actual time. return msToExpirationTime(now()); } // We're not inside React, so we may be in the middle of a browser event. if (currentEventTime !== NoWork) { // Use the same start time for all updates until we enter React again. return currentEventTime; } // This is the first update since React yielded. Compute a new start time. currentEventTime = msToExpirationTime(now()); return currentEventTime; }
// 这里对应指定context模式,也就是外部强制更新 if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering return renderExpirationTime; }
let expirationTime; // 这里对应suspense模式 if (suspenseConfig !== null) { // Compute an expiration time based on the Suspense timeout. expirationTime = computeSuspenseExpiration( currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION, ); } else { // 这里对应异步模式 // Compute an expiration time based on the Scheduler priority. switch (priorityLevel) { case ImmediatePriority: expirationTime = Sync; break; case UserBlockingPriority: expirationTime = computeInteractiveExpiration(currentTime); break; case NormalPriority: case LowPriority: expirationTime = computeAsyncExpiration(currentTime); break; case IdlePriority: expirationTime = Idle; break; default: invariant(false, 'Expected a valid priority level'); } }
// If we're in the middle of rendering a tree, do not update at the same // expiration time that is already rendering. if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; }