React16.8源码expirationTime大小与优先级的问题

updateContainer里的expirationTime

updateContainer里计算了expirationTime,这里网上说的是越大任务优先级越高,但后面为什么unstable_scheduleCallback里又去算了一遍,且算法完全不同

export function updateContainer(
  element: ReactNodeList,
  container: OpaqueRoot,
  parentComponent: ?React$Component<any, any>,
  callback: ?Function,
): ExpirationTime {
  // 取出容器的 fiber 对象,也就是 fiber root
  const current = container.current;
  // 计算时间
  const currentTime = requestCurrentTime();
  // expirationTime 代表优先级,数字越大优先级越高
  // sync 的数字是最大的,所以优先级也是最高的
  const expirationTime = computeExpirationForFiber(currentTime, current);
  return updateContainerAtExpirationTime(
    element,
    container,
    parentComponent,
    expirationTime,
    callback,
  );
}
//computeExpirationForFiber部分代码
  let expirationTime;
  const priorityLevel = getCurrentPriorityLevel();
  switch (priorityLevel) {
    case ImmediatePriority:
      expirationTime = Sync;//MAX_SIGNED_31_BIT_INT:1073741823
      break;
    case UserBlockingPriority:
      // TODO: Rename this to computeUserBlockingExpiration
      expirationTime = computeInteractiveExpiration(currentTime);
      break;
    case NormalPriority:
    case LowPriority: // TODO: Handle LowPriority
      // TODO: Rename this to... something better.
      expirationTime = computeAsyncExpiration(currentTime);
      break;
    case IdlePriority:
      expirationTime = Never;
      break;
    default:
      invariant(false, 'Expected a valid priority level');
  }

unstable_scheduleCallback中的expirationTime

这里ImmediatePriority对应的IMMEDIATE_PRIORITY_TIMEOUT是-1,IdlePriority(Never times out)才是最大的整数,那算出来的expirationTime就变成了越小优先级越高了

switch (priorityLevel) {
      case ImmediatePriority:
        expirationTime = startTime + IMMEDIATE_PRIORITY_TIMEOUT;
        break;
      case UserBlockingPriority:
        expirationTime = startTime + USER_BLOCKING_PRIORITY;
        break;
      case IdlePriority:
        expirationTime = startTime + IDLE_PRIORITY;//maxSigned31BitInt:1073741823
        break;
      case LowPriority:
        expirationTime = startTime + LOW_PRIORITY_TIMEOUT;
        break;
      case NormalPriority:
      default:
        expirationTime = startTime + NORMAL_PRIORITY_TIMEOUT;
    }

疑问

1.查了下资料updateContainer中的expirationTime经过一个算法有将趋于相同的两个到期时间的更新任务计算成同一个expirationTime,以达到合并update队列批量更新的功能,但是源码里我也没看到哪里做了特别的处理啊,有没有人知道是在哪里合并的。。。
2.为什么两个地方分别用两种不同的方式来计算expirationTime,且代表的优先级关系是向反的,updateContainer里到期时间越大说的是优先级越高好难理解,为什么React这么处理啊
3.大家有没有专门介绍expirationTime的文章推荐,我看了很多篇都没把这里说清楚只是在介绍fiber执行的流程

阅读 2.6k
2 个回答

目前版本的确是expirationTime越大优先级越大,但这块出现过变更,以前是越小越大

新手上路,请多包涵

计算ExpirationTime返回值是各个公式MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0),其中MAGIC_NUMBER_OFFSET是个常量值为1073741822,ms是window.performance.now()(这个时间一般是从地址栏输入地址回车后到执行这个方法中间间隔的毫秒数),也就是ms越小,优先级应该越高,当ms越小时,ExpirationTime就越大,自然ExpirationTime越大,优先级越高;

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏