计算公式

const MAX_SIGNED_31_BIT_INT = Math.pow(2, 30) - 1
export const NoWork = 0;
export const Never = 1;
const UNIT_SIZE = 10;
const MAGIC_NUMBER_OFFSET = MAX_SIGNED_31_BIT_INT - 1;
// 1 unit of expiration time represents 10ms.
export function msToExpirationTime(ms) {
// Always add an offset so that we don't clash with the magic number for NoWork.
return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0);
}
export function expirationTimeToMs(expirationTime) {
return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
}
function ceiling(num, precision) {
return (((num / precision) | 0) + 1) * precision;
}
function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
return (
MAGIC_NUMBER_OFFSET -
ceiling(
MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE,
bucketSizeMs / UNIT_SIZE,
)
);
}
export const LOW_PRIORITY_EXPIRATION = 5000;
export const LOW_PRIORITY_BATCH_SIZE = 250;
export function computeAsyncExpiration(currentTime) {
return computeExpirationBucket(
currentTime,
LOW_PRIORITY_EXPIRATION,
LOW_PRIORITY_BATCH_SIZE,
);
}
export const HIGH_PRIORITY_EXPIRATION = __DEV__ ? 500 : 150;
export const HIGH_PRIORITY_BATCH_SIZE = 100;
export function computeInteractiveExpiration(currentTime) {
return computeExpirationBucket(
currentTime,
HIGH_PRIORITY_EXPIRATION,
HIGH_PRIORITY_BATCH_SIZE,
);
}

computeAsyncExpiration 函数化简后得到如下公式, 针对这个公式目前的心得如下:

  1. 抹平传入的 bucketSizeMs 精度误差, 为 batch 作准备;
  2. currentTime 越大, 相应的 expirationTime 的结果如下图所示;

const MAX_SIGNED_31_BIT_INT = Math.pow(2, 30) - 1
const MAGIC_NUMBER_OFFSET = MAX_SIGNED_31_BIT_INT - 1;
function ceiling(num, precision) {
return (((num / precision) | 0) + 1) * precision;
}
function computeExpirationBucket(currentTime) {
return (
MAGIC_NUMBER_OFFSET -
ceiling(
MAGIC_NUMBER_OFFSET - currentTime + 500,
25,
)
);
}

ceiling 函数的作用: 根据 precision 的精度取值

ceiling(25, 25) // 50
ceiling(26, 25) // 50
ceiling(27, 25) // 50
...
ceiling(49, 25) // 50
ceiling(50, 25) // 75
ceiling(51, 25) // 75