function computeExpirationForFiber(currentTime, fiber){
const mode = fiber.mode;
if ((mode & BlockingMode) === NoMode) {
return Sync;
}
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');
}
}
computeInteractiveExpiration
和computeAsyncExpiration
都是采用下面的最终公式计算得到的,差别在于$p_1$
和$p_2$
的值不同。computeInteractiveExpiration
的$p_1$
和$p_2$
的值更小,得到的结果就更大。
m = 2^{30} - 3
c = m - n
c_1 = m - c + \frac {p_1} {10} = n + \frac {p_1} {10}
c_2 = \frac {p_2} {10}
r = [ \frac {c_1} {c_2} + 1]c_2
e = m - r
e = m - [ \frac {c_1} {c_2} + 1]c_2
e = m - [ \frac {n + \frac {p_1} {10} } {\frac {p_2} {10}} + 1]\frac {p_2} {10} ······ (最终公式)
其中
$m$
表示 MAGIC_NUMBER_OFFSET
$c$
表示 currentTime
$n$
表示 now()
,可以理解为Date.now() / 10
$p_1$
表示 _PRIORITY_EXPIRATION
$p_2$
表示 _PRIORITY_BATCH_SIZE
$e$
表示 expirationTime
$c_1$
、$c_2$
、$r$
为中间值, 中括号表示取整
expirationTime
值越大,优先级越高
在React中一个单位的expirationTime
表示10ms,
从最终公式
中可以看到
以LOW_PRIORITY_BATCH_SIZE
即$p_1= 250$
为例,now() 在0到25(25个单位,表示250ms)之间计算得到的过期时间相同,他们将产生的更新将合并到一起,$p_2$
越小,更新粒度就越小,LOW_PRIORITY_BATCH_SIZE
将250ms产生的更新合并到一起,HIGH_PRIORITY_BATCH_SIZE
将100ms产生的更新合并到一起