batchedUpdate
// 1 unit of expiration time represents 10ms.
export function msToExpirationTime(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);
}
得出一个时间进行批量更新
this.setState({
count: 1
})
console.log(this.state.count)
this.setState({
count: 1
})
console.log(this.state.count)
setState 没有进入 batchedUpdate
try{
return fn(a)
} finally{
isBatchingUpdates = previousIsBatchingUpdates;
// 当我们的setState 都调用完毕后,isBatchingUpdates 会变成false。 调用performSyncWork
if(!isBatchingUpdates && !isRendering){
performSyncWork();
}
}
setTimeout(()=>{
this.setState({
count: 1
})
}, 0)
如果我们放在 setTimeout 里面,setTimeout的执行上下文变为window isBatchingUpdates 每次都会为 恢复原样的情况, 但是这样会变得应用性能很低
setState 本身的方法是同步的,但是调用后不代表立马就更新了,这个更新是根据我们当前的执行上下文来判断的, 如果出于批量更新的话,就不会更新
状态更新和执行回调的步骤是不一样的,更新状态在渲染阶段,而调用回调是在提交阶段,所以肯定是批量更新之后在一起回调的。
被打断的任务会回溯到最初的状态重新执行新的任务
FiberRoot 是只有一个的,也就是你的 container 对应的 fiber 对象
reactScheduler
维护时间片
模拟requestIdleCallback
调度列表
function scheduleCallbackWithExpirationTime(
root: FiberRoot,
expirationTime: ExpirationTime,
) {
if (callbackExpirationTime !== NoWork) {
// A callback is already scheduled. Check its expiration time (timeout).
if (expirationTime < callbackExpirationTime) {
// Existing callback has sufficient timeout. Exit.
return;
} else {
if (callbackID !== null) {
// Existing callback has insufficient timeout. Cancel and schedule a
// new one.
cancelDeferredCallback(callbackID);
}
}
// The request callback timer is already running. Don't start a new one.
} else {
startRequestCallbackTimer();
}
callbackExpirationTime = expirationTime;
const currentMs = now() - originalStartTimeMs;
const expirationTimeMs = expirationTimeToMs(expirationTime);
const timeout = expirationTimeMs - currentMs;
callbackID = scheduleDeferredCallback(performAsyncWork, {timeout});
}
export {
unstable_now as now,
unstable_scheduleCallback as scheduleDeferredCallback,
unstable_shouldYield as shouldYield,
unstable_cancelCallback as cancelDeferredCallback,
} from 'scheduler';
// 先导入进来, 在替换名字
异步任务是会交给 scheduler 来做,而这个 callback 就是交给 scheduler 的回调,回调里面其实就是 work 本身.
在组件中调用setState, react 都会将这个组件标记为dirty。 再一次事件循环结束后,Reat回走所所有被标记为dirty 的组件,并对它们重新渲染。
最后更新于
这有帮助吗?