You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// requestWork is called by the scheduler whenever a root receives an update.// It's up to the renderer to call renderRoot at some point in the future.functionrequestWork(root: FiberRoot,expirationTime: ExpirationTime){// 把当前 root设置为最高优先级addRootToSchedule(root,expirationTime);if(isRendering){// 在render过程当中, 此时直接return// Prevent reentrancy. Remaining work will be scheduled at the end of// the currently rendering batch.return;}// 批量处理相关// 调用 setState 时在 enqueueUpdates 前 batchedUpdates 会把 isBatchingUpdates 设置成 trueif(isBatchingUpdates){// Flush work at the end of the batch.if(isUnbatchingUpdates){// ...unless we're inside unbatchedUpdates, in which case we should// flush it now.nextFlushedRoot=root;nextFlushedExpirationTime=Sync;performWorkOnRoot(root,Sync,false);}return;}// TODO: Get rid of Sync and use current time?if(expirationTime===Sync){// 同步的调用 js 代码performSyncWork();}else{// 异步调度 独立的 react 模块包,利用浏览器有空闲的时候进行执行,设置 deadline 在此之前执行scheduleCallbackWithExpirationTime(root,expirationTime);}}
首先调用了addRootToSchedule:
/** * 将 root 加入到调度队列 * * @param {FiberRoot} root * @param {ExpirationTime} expirationTime */functionaddRootToSchedule(root: FiberRoot,expirationTime: ExpirationTime){// Add the root to the schedule.// Check if this root is already part of the schedule.// root.nextScheduledRoot 用来判断是否有异步任务正在调度, 为 null 时会增加 nextScheduledRoot// 这个 root 还没有进入过调度if(root.nextScheduledRoot===null){// This root is not already scheduled. Add it.root.expirationTime=expirationTime;if(lastScheduledRoot===null){// lastScheduledRoot firstScheduledRoot 是单向链表结构,表示多个 root 更新// 这里只有一个 root 只会在这里执行firstScheduledRoot=lastScheduledRoot=root;root.nextScheduledRoot=root;}else{// 有个多个root 时进行单向链表的插入操作lastScheduledRoot.nextScheduledRoot=root;lastScheduledRoot=root;lastScheduledRoot.nextScheduledRoot=firstScheduledRoot;}}else{// This root is already scheduled, but its priority may have increased.// 传入的 root 已经进入过调度, 把 root 的优先级设置最高constremainingExpirationTime=root.expirationTime;// 如果 root 的 expirationTime 是同步或者优先级低,增加为计算出的最高优先级if(expirationTime>remainingExpirationTime){// Update the priority.// 把当前 root 的优先级设置为当前优先级最高的root.expirationTime=expirationTime;}}}
requestWork
首先说明以下
requestWork
的核心功能:root
节点加入到root
调度队列中expirationTime
的类型判断调度的类型下面,我们来详细分析下
requestWork
的流程。首先来看requestWork
:首先调用了
addRootToSchedule
:作用比较清晰:
root
是否调度过, 单个或多个root
构建成单向链表结构回到
requestWork
,分成了三个分支:我们来分别解释一下:
isRendering
顾名思义在render
过程当中, 此时直接返回return
。batchedUpdate
批处理的时候,将isRendering
置成true
,这样每次在执行setState
时,都会走isRendering
的分支直接返回,阻止更新,相当于暂停住,当第二个setState
时依旧直接返回,避免出现频繁式的更新,也就是批处理。isBatchingUpdates
中又有一个isUnbatchingUpdates
分支。isUnbatchingUpdates
会在执行unbatchedUpdates()
时设置为true
。 也就是在首次渲染的时候不需要进行批处理,所以就会进行立即更新。 这里的两个变量名可能会造成误解,isBatchingUpdates
和isUnbatchingUpdates
这两个变量并不是互斥的,而是在两个方法中设置的哨兵变量。如果是批处理的过程中的话,也会直接
return
。当前面的
expirationTime
被设置成了同步任务的时候,就会立即执行。 剩余的则会进入scheduleCallbackWithExpirationTime
通过ExpirationTime
进行调度。The text was updated successfully, but these errors were encountered: