当用 autorun
时,函数会被当即执行一次,而后每当它的依赖有任何改变,autorun
都会执行一次。react
生成 name
api
判断 opts
上是否有 scheduler
和 delay
。若是都没有,则为 true
,不然为 false
。函数
runSync 为 truethis
实例化 Reaction
,传入 name
、onInvalidate
函数和错误处理函数。spa
reaction = new Reaction(
name,
function(this: Reaction) {
this.track(reactionRunner);
},
opts.onError
);
复制代码
runSync 为 falsecode
根据传入参数,生成本身的调度 scheduler
函数server
实例化 Reaction
,传入 name
、onInvalidate
函数和错误处理函数。对象
reaction = new Reaction(
name,
() => {
if (!isScheduled) {
isScheduled = true;
scheduler(() => {
isScheduled = false;
if (!reaction.isDisposed) reaction.track(reactionRunner);
});
}
},
opts.onError
);
复制代码
把 this
添加到全局的待处理列表 pendingReactions
中事件
开始执行 runReactions
事务
判断当前全局中是否处于处理事务状态或处理反应 reactions
阶段,若是是则返回,什么都不作。不然执行 reactionScheduler(runReactionsHelper)
,也就是执行 runReactionsHelper
if (globalState.inBatch > 0 || globalState.isRunningReactions) return
reactionScheduler(runReactionsHelper)
复制代码
把全局状态中 isRunningReactions
设为 true
,经过 pendingReactions
取到全部待处理 Reaction
实例,并清空 pendingReactions
列表
遍历全部实例,针对每个实例都调用其自身的 runReaction
,遍历结束后把全局 isRunningReactions
改成 false
runReaction() {
// 当前是否已经清除
if (!this.isDisposed) {
// 开始处理事务,设置 global.inBatch,令其值 +1
startBatch()
this._isScheduled = false
// 判断是否须要追踪,当前 dependenciesState 处于 NOT_TRACKING,shouldCompute 会对于此状态返回 true
if (shouldCompute(this)) {
// 改变当前状态
this._isTrackPending = true
try {
// 执行传递进来的函数
this.onInvalidate()
// 判断当前 _isTrackPending 状态和全局监听器 spy,若是有全局监听器,则发送事件,类型为 scheduled-reaction
if (this._isTrackPending && isSpyEnabled()) {
// onInvalidate didn't trigger track right away..
spyReport({
name: this.name,
type: "scheduled-reaction"
})
}
} catch (e) {
// 错误处理
this.reportExceptionInDerivation(e)
}
}
// 结束处理事务
endBatch()
}
}
复制代码
执行 track
函数,参数为 reactionRunner
。
// api/autorun.ts
function(this: Reaction) {
this.track(reactionRunner);
}
// core/reaction.ts
function track(fn){
startBatch()
...
const result = trackDerivedFunction(this, fn, undefined)
...
}
// core/derivation.ts
function trackDerivedFunction(derivation, f, context){
...
result = f.call(context)
...
bindDependencies(derivation)
}
复制代码
startBatch
,再次使 global.inBatch
值 +1
spy
,有则发送事件,类型为 reaction
,并记录当前时间_isRunning
为 true
dependenciesState
为 UP_TO_DATE
,UP_TO_DATE
意味着值是新的observing
属性值,若是有值,则遍历,把每一项的 lowestObserverState
都设为 UP_TO_DATE
derivation
设置到全局对象上,同时给 derivation
新增属性globalState.disableErrorBoundaries
,调用传入的函数,收集新的依赖trackingDerivation
恢复原状onBecomeStale
,更新全部的依赖项this.isDisposed
判断须要清除 autorun
reaction
和 derivation
耗时