第一次寫這種文章,理解應該不深,望各位dalao們指點指點javascript
bb不來,純乾貨java
Vue.watch(() => {
console.log("watch OK!!!");
app.querySelector('p').textContent = count.value;
});
複製代碼
// 簡化後
export function watch(effectOrSource, effectOrOptions,options) {
if (isFunction(effectOrOptions)) {
} else {
// 執行這裏
return doWatch(effectOrSource, null, effectOrOptions)
}
}
複製代碼
doWatch(source,cb,options){
// source 爲fn 其餘 在這裏都不重要
// 1. 將source 處理成 getter
// 2. 將getter 打包成
// 3.經過effect 打包成一個訂閱函數 即 runner 變量
// 3.1 ps: effect 很重要 下面列出了函數代碼
// 4. 執行 scheduler (scheduler是判斷flush獲得的)
let scheduler = job => {
queuePostRenderEffect(job, suspense)
}
// 5.執行 queuePostRenderEffect 後 會將函數添加到隊列並執行它
// 5.1 `下面列出了這個函數`
// 6.end 這個函數的事情作完了
}
// 這個函數會執行queuePostFlushCb而後將訂閱函數放入(任務)隊列
function queuePostRenderEffect(fn,suspense){
if (suspense !== null && !suspense.isResolved) {
// 不重要
} else {
// 執行 queuePostFlushCb
queuePostFlushCb(fn)
}
}
// 這個函數最大的功能就是 執行nextTick和添加隊列
function queuePostFlushCb(cb: Function | Function[]) {
// ...
// 一些不重要的代碼
// ...
// isFlushing不重要 最終會 執行 nextTick
if (!isFlushing) {
nextTick(flushJobs)
}
}
// 異步執行函數
function nextTick(fn?: () => void) {
return fn ? p.then(fn) : p
}
複製代碼
effect( fn,options) {
// ...
// 一些不重要的代碼
// ...
// 創造一個 effect對象 用於綁定一些屬性和不容許重複綁定
const effect = createReactiveEffect(fn, options)
// ...
// 一些不重要的代碼
// ...
return effect
}
// 建立訂閱函數
function createReactiveEffect(fn, options) {
const effect = function effect(...args) {
// run 函數 下面貼了代碼
return run(effect as ReactiveEffect, fn, args)
}
effect.isEffect = true
effect.active = true
effect.raw = fn
effect.scheduler = options.scheduler
effect.onTrack = options.onTrack
effect.onTrigger = options.onTrigger
effect.onStop = options.onStop
effect.computed = options.computed
effect.deps = []
return effect
}
複製代碼
// 將訂閱函數添加到 等待隊列後,執行fn函數
// 若是fn中有 可觸發的data getter 就將函數訂閱到該發佈者 // 這裏不知道怎麼說了
function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
// 當 active 被中止 就不須要了訂閱了 直接綁定便可
if (!effect.active) {
return fn(...args)
}
// 若是隊列中不存在就表示此effect能夠被訂閱
if (activeReactiveEffectStack.indexOf(effect) === -1) {
cleanup(effect)
try {
// 先將 effect 添加到 等待訂閱的隊列
activeReactiveEffectStack.push(effect)
// 執行以後會觸發getter 而後將effect訂閱到隊列
return fn(...args)
} finally {
// 當訂閱以後就退出來
activeReactiveEffectStack.pop()
}
}
}
複製代碼