此文中的可能,只是在看源码时的记录笔记,暂时没有解决。
中断的可能
React-recociler中的参数可分为基础的、Mutation(变化)、Persistence(持续;固执;存留)、Hydration(水合作用)。
// 下面标识了中断的可能
function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
if (enableUserTimingAPI) {
if (!supportsUserTiming) {
return;
}
var warning = null;
if (interruptedBy !== null) {
if (interruptedBy.tag === HostRoot) {
warning = 'A top-level update interrupted the previous render';//@中断可能一
} else {
var componentName = getComponentName(interruptedBy.type) || 'Unknown';
warning = 'An update to ' + componentName
+ ' interrupted the previous render';//@中断可能二
}
} else if (commitCountInCurrentWorkLoop > 1) {
warning = 'There were cascading updates';
}
commitCountInCurrentWorkLoop = 0;
var label = didCompleteRoot ?
'(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
// Pause any measurements until the next loop.
pauseTimers();
endMark(label, '(React Tree Reconciliation)', warning);
}
}
延迟执行
if (finishedWork !== null) {
// We've completed the root. Commit it.
completeRoot(root, finishedWork, expirationTime);
}
在completeRoot 中有一段代码,可阻止当前提交,等待下一次提价的:
function completeRoot(root: FiberRoot, finishedWork: Fiber,
expirationTime: ExpirationTime): void {
// Check if there's a batch that matches this expiration time.
const firstBatch = root.firstBatch;
if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
if (completedBatches === null) {
completedBatches = [firstBatch];
} else {
completedBatches.push(firstBatch);
}
if (firstBatch._defer) {// 阻止提交
// This root is blocked from committing by a batch. Unschedule it until
// we receive another update.
root.finishedWork = finishedWork;
root.expirationTime = NoWork;
return;
}
}
// ...
commitRoot(root, finishedWork);
}
firstBatch._defer 为true,可阻止提交。
firstBatch._defer 为true就阻止本次提交并等待下一次提交。查了查代码,发现 _defer 是在 ReactDOM 源码中packages\react-dom\src\client\ReactDOM.js 中 ReactBatch,代码如下:
function ReactBatch(root: ReactRoot) {
const expirationTime = computeUniqueAsyncExpiration();
this._expirationTime = expirationTime;//设置的时间
this._root = root;
this._next = null;
this._callbacks = null;
this._didComplete = false;
this._hasChildren = false;
this._children = null;
this._defer = true;//初始设置为true
}
/**此处的重点不在这,省略....代码*/