原文理解:juejin.cn/post/684490…
react版本:16.8.6
异步:手动开启批量更新的api:
unstable_batchedUpdates: batchedUpdates$1
function batchedUpdates$1(fn, a) {
var previousIsBatchingUpdates = isBatchingUpdates;
isBatchingUpdates = true;
try {
return fn(a);
} finally {
isBatchingUpdates = previousIsBatchingUpdates;
if (!isBatchingUpdates && !isRendering) {
performSyncWork();
}
}
}
是否批量更新是由变量isBatchingUpdates控制的。 在合成事件中:
function interactiveUpdates$1(fn, a, b) {
// If there are any pending interactive updates, synchronously flush them.
// This needs to happen before we read any handlers, because the effect of
// the previous event may influence which handlers are called during
// this event.
if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) {
// Synchronously flush pending interactive updates.
performWork(lowestPriorityPendingInteractiveExpirationTime, false);
lowestPriorityPendingInteractiveExpirationTime = NoWork;
}
var previousIsBatchingUpdates = isBatchingUpdates;
isBatchingUpdates = true;
try {
return scheduler.unstable_runWithPriority(scheduler.unstable_UserBlockingPriority, function () {
return fn(a, b);
});
} finally {
isBatchingUpdates = previousIsBatchingUpdates;
if (!isBatchingUpdates && !isRendering) {
performSyncWork();
}
}
}
1:除了设置isBatchingUpdates为true以外,下面是一个try-finally代码块。这个fn函数调用,就是调用合成事件回调,然后finally中才调用批量更新performSyncWork。解决问题1:setstate为什么是异步的。
instance.componentDidMount();
commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
2:声明周期中同合成事件一样,先调用生命周期函数,再调用批量更新
同步
1:原生事件和setTimeout,Promise中的可以同步,同步的原因是事件循环机制 2:unstable_batchedUpdates()中可以实现同步
function batchedUpdates$1(fn, a) {
var previousIsBatchingUpdates = isBatchingUpdates;
isBatchingUpdates = true;
try {
return fn(a);
} finally {
isBatchingUpdates = previousIsBatchingUpdates;
if (!isBatchingUpdates && !isRendering) {
performSyncWork();
}
}
}
注意:
setState异步及批量更新是因为生命周期及合成事件通过try...finally进行了批量调用。但是setState本身并没有调用。批量更新。因此通过事件循环放在队列中,是可以同步进行的。