Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 95x 95x 95x 95x 95x 95x 95x 9x 9x 7x 7x 95x 7x 9x 7x 7x 9x 9x 9x 9x 9x 9x 9x 18x 18x 2x 2x 16x 9x 9x 9x 9x 9x 7x 9x 18x 18x 2x 18x 9x 31x 20x 20x 11x 22x 22x 95x 9x | import { Dep } from './dep' import { ReactiveEffect } from './effect' import { ComputedGetter, ComputedRef } from './computed' import { ReactiveFlags, toRaw } from './reactive' import { trackRefValue, triggerRefValue } from './ref' const tick = /*#__PURE__*/ Promise.resolve() const queue: any[] = [] let queued = false const scheduler = (fn: any) => { queue.push(fn) if (!queued) { queued = true tick.then(flush) } } const flush = () => { for (let i = 0; i < queue.length; i++) { queue[i]() } queue.length = 0 queued = false } class DeferredComputedRefImpl<T> { public dep?: Dep = undefined private _value!: T private _dirty = true public readonly effect: ReactiveEffect<T> public readonly __v_isRef = true public readonly [ReactiveFlags.IS_READONLY] = true constructor(getter: ComputedGetter<T>) { let compareTarget: any let hasCompareTarget = false let scheduled = false this.effect = new ReactiveEffect(getter, (computedTrigger?: boolean) => { if (this.dep) { if (computedTrigger) { compareTarget = this._value hasCompareTarget = true } else if (!scheduled) { const valueToCompare = hasCompareTarget ? compareTarget : this._value scheduled = true hasCompareTarget = false scheduler(() => { if (this.effect.active && this._get() !== valueToCompare) { triggerRefValue(this) } scheduled = false }) } // chained upstream computeds are notified synchronously to ensure // value invalidation in case of sync access; normal effects are // deferred to be triggered in scheduler. for (const e of this.dep) { if (e.computed instanceof DeferredComputedRefImpl) { e.scheduler!(true /* computedTrigger */) } } } this._dirty = true }) this.effect.computed = this as any } private _get() { if (this._dirty) { this._dirty = false return (this._value = this.effect.run()!) } return this._value } get value() { trackRefValue(this) // the computed ref may get wrapped by other proxies e.g. readonly() #3376 return toRaw(this)._get() } } export function deferredComputed<T>(getter: () => T): ComputedRef<T> { return new DeferredComputedRefImpl(getter) as any } |