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
functionscheduleWork(fiber: Fiber,expirationTime: ExpirationTime){constroot=scheduleWorkToRoot(fiber,expirationTime);if(root===null){// 找不到 rootFiber 直接 returnif(__DEV__){switch(fiber.tag){caseClassComponent:
warnAboutUpdateOnUnmounted(fiber,true);break;caseFunctionComponent:
caseForwardRef:
caseMemoComponent:
caseSimpleMemoComponent:
warnAboutUpdateOnUnmounted(fiber,false);break;}}return;}// isWorking: 正在执行渲染,有任务正在进行当中 在后续任务正在执行 可能被中断的情况。。!isWorking 代表没任何任务正在进行// nextRenderExpirationTime !== NoWork:任务可能是异步任务,并且执行到一半没有执行完,现在要把执行权交给浏览器去执行更高优先级的任务,// expirationTime > nextRenderExpirationTim:新的任务的 expirationTime 高于目前任务的 expirationTime// 新优先级任务打断低优先级任务的操作if(!isWorking&&nextRenderExpirationTime!==NoWork&&expirationTime>nextRenderExpirationTime){// This is an interruption. (Used for performance tracking.)// 给开发工具用的,用来展示被哪个节点打断了异步任务interruptedBy=fiber;// 新优先级任务打断低优先级任务的操作。resetStack();}markPendingPriorityLevel(root,expirationTime);if(// If we're in the render phase, we don't need to schedule this root// for an update, because we'll do it before we exit...!isWorking||isCommitting||// ...unless this is a different root than the one we're rendering.nextRoot!==root){constrootExpirationTime=root.expirationTime;requestWork(root,rootExpirationTime);}if(nestedUpdateCount>NESTED_UPDATE_LIMIT){// Reset this back to zero so subsequent updates don't throw.nestedUpdateCount=0;invariant(false,"Maximum update depth exceeded. This can happen when a "+"component repeatedly calls setState inside "+"componentWillUpdate or componentDidUpdate. React limits "+"the number of nested updates to prevent infinite loops.");}}
if(!isWorking&&nextRenderExpirationTime!==NoWork&&expirationTime>nextRenderExpirationTime){// This is an interruption. (Used for performance tracking.)// 给开发工具用的,用来展示被哪个节点打断了异步任务interruptedBy=fiber;// 新优先级任务打断低优先级任务的操作。resetStack();}
if(// If we're in the render phase, we don't need to schedule this root// for an update, because we'll do it before we exit...!isWorking||isCommitting||// ...unless this is a different root than the one we're rendering.nextRoot!==root){constrootExpirationTime=root.expirationTime;requestWork(root,rootExpirationTime);}
scheduleWork
ReactDOM.render
、setState
、forceUpdate
最终都调用了scheduleWork
,而它做了什么工作呢?总结下,
scheduleWork
做的工作就是:FiberRoot
节点。ReactDOM.render
的时候我们传给scheduleWork
就是FiberRoot
,setState
、forceUpdate
一般都是传递的是某个组件的对应的fiber
节点,这时候就需要找到FiberRoot
节点scheduleWorkToRoot
scheduleWork
最开始先调用了scheduleWorkToRoot
,这一步非常重要:它主要做了以下几件事:
1、根据当前
Fiber
节点向上寻找对应的的root
节点2、给更新节点的父节点链上的每个节点的
expirationTime
设置为这个update
的expirationTime
,除非他本身时间要小于expirationTime
3、给更新节点的父节点链上的每个节点的
childExpirationTime
设置为这个update
的expirationTime
,除非他本身时间要小于expirationTime
4、最终返回
root
节点的Fiber
对象resetStack
scheduleWork
调用了scheduleWorkToRoot
最终返回了rootFiber
节点后呢,我们执行了一个判断,其中调用了一个很重要的方法resetStack
:这里的意思就是目前没有任何任务在执行,并且之前有执行过任务,同时当前的任务比之前执行的任务过期时间要早(也就是优先级要高)。
那么这种情况会出现在什么时候呢?答案就是:上一个任务是异步任务(优先级很低,超时时间是 502ms),并且在上一个时间片(初始是 33ms)任务没有执行完,而且等待下一次
requestIdleCallback
的时候新的任务进来了,并且超时时间很短(52ms 或者 22ms 甚至是Sync
),那么优先级就变成了先执行当前任务,也就意味着上一个任务被打断了(interrupted
)被打断的任务会从当前节点开始往上推出
context
,因为在React
只有一个stack
,而下一个任务会从头开始的,所以在开始之前需要清空之前任务的的stack
。这里的
nextUnitOfWork
用于记录render
阶段Fiber
树遍历过程中下一个需要执行的节点。在resetStack
中分别被重置,他只会指向workInProgress
。markPendingPriorityLevel(后面补充)
调用 requestWork
这个判断条件就比较简单了,
!isWorking || isCommitting
简单来说就是要么处于没有work
的状态,要么只能在render
阶段,不能处于commit
阶段。在符合条件之后就去执行
requestWork
了。The text was updated successfully, but these errors were encountered: