此文中的可能,只是在看源码时的记录笔记,暂时没有解决。

中断的可能

React-recociler中的参数可分为基础的、Mutation(变化)、Persistence(持续;固执;存留)、Hydration(水合作用)。

  1. // 下面标识了中断的可能
  2. function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
  3. if (enableUserTimingAPI) {
  4. if (!supportsUserTiming) {
  5. return;
  6. }
  7. var warning = null;
  8. if (interruptedBy !== null) {
  9. if (interruptedBy.tag === HostRoot) {
  10. warning = 'A top-level update interrupted the previous render';//@中断可能一
  11. } else {
  12. var componentName = getComponentName(interruptedBy.type) || 'Unknown';
  13. warning = 'An update to ' + componentName
  14. + ' interrupted the previous render';//@中断可能二
  15. }
  16. } else if (commitCountInCurrentWorkLoop > 1) {
  17. warning = 'There were cascading updates';
  18. }
  19. commitCountInCurrentWorkLoop = 0;
  20. var label = didCompleteRoot ?
  21. '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
  22. // Pause any measurements until the next loop.
  23. pauseTimers();
  24. endMark(label, '(React Tree Reconciliation)', warning);
  25. }
  26. }

延迟执行

  1. if (finishedWork !== null) {
  2. // We've completed the root. Commit it.
  3. completeRoot(root, finishedWork, expirationTime);
  4. }

在completeRoot 中有一段代码,可阻止当前提交,等待下一次提价的:

  1. function completeRoot(root: FiberRoot, finishedWork: Fiber,
  2. expirationTime: ExpirationTime): void {
  3. // Check if there's a batch that matches this expiration time.
  4. const firstBatch = root.firstBatch;
  5. if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
  6. if (completedBatches === null) {
  7. completedBatches = [firstBatch];
  8. } else {
  9. completedBatches.push(firstBatch);
  10. }
  11. if (firstBatch._defer) {// 阻止提交
  12. // This root is blocked from committing by a batch. Unschedule it until
  13. // we receive another update.
  14. root.finishedWork = finishedWork;
  15. root.expirationTime = NoWork;
  16. return;
  17. }
  18. }
  19. // ...
  20. commitRoot(root, finishedWork);
  21. }

firstBatch._defer 为true,可阻止提交。
firstBatch._defer 为true就阻止本次提交并等待下一次提交。查了查代码,发现 _defer 是在 ReactDOM 源码中packages\react-dom\src\client\ReactDOM.js 中 ReactBatch,代码如下:

  1. function ReactBatch(root: ReactRoot) {
  2. const expirationTime = computeUniqueAsyncExpiration();
  3. this._expirationTime = expirationTime;//设置的时间
  4. this._root = root;
  5. this._next = null;
  6. this._callbacks = null;
  7. this._didComplete = false;
  8. this._hasChildren = false;
  9. this._children = null;
  10. this._defer = true;//初始设置为true
  11. }
  12. /**此处的重点不在这,省略....代码*/