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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 100x 100x 1663x 1663x 1663x 1663x 2x 2x 20x 19x 19x 19x 19x 19x 1x 1x 2687x 2669x 217x 217x 231x 217x 4x 217x 1x 1x 217x 1x 1x 217x 100x 1x 100x 1613x 1322x 100x 2x 100x 5x 4x 1x 1x | import { ReactiveEffect } from './effect' import { warn } from './warning' let activeEffectScope: EffectScope | undefined export class EffectScope { /** * @internal */ active = true /** * @internal */ effects: ReactiveEffect[] = [] /** * @internal */ cleanups: (() => void)[] = [] /** * only assigned by undetached scope * @internal */ parent: EffectScope | undefined /** * record undetached scopes * @internal */ scopes: EffectScope[] | undefined /** * track a child scope's index in its parent's scopes array for optimized * removal * @internal */ private index: number | undefined constructor(detached = false) { if (!detached && activeEffectScope) { this.parent = activeEffectScope this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push( this ) - 1 } } run<T>(fn: () => T): T | undefined { if (this.active) { const currentEffectScope = activeEffectScope try { activeEffectScope = this return fn() } finally { activeEffectScope = currentEffectScope } } else if (__DEV__) { warn(`cannot run an inactive effect scope.`) } } /** * This should only be called on non-detached scopes * @internal */ on() { activeEffectScope = this } /** * This should only be called on non-detached scopes * @internal */ off() { activeEffectScope = this.parent } stop(fromParent?: boolean) { if (this.active) { let i, l for (i = 0, l = this.effects.length; i < l; i++) { this.effects[i].stop() } for (i = 0, l = this.cleanups.length; i < l; i++) { this.cleanups[i]() } if (this.scopes) { for (i = 0, l = this.scopes.length; i < l; i++) { this.scopes[i].stop(true) } } // nested scope, dereference from parent to avoid memory leaks if (this.parent && !fromParent) { // optimized O(1) removal const last = this.parent.scopes!.pop() Iif (last && last !== this) { this.parent.scopes![this.index!] = last last.index = this.index! } } this.active = false } } } export function effectScope(detached?: boolean) { return new EffectScope(detached) } export function recordEffectScope( effect: ReactiveEffect, scope: EffectScope | undefined = activeEffectScope ) { if (scope && scope.active) { scope.effects.push(effect) } } export function getCurrentScope() { return activeEffectScope } export function onScopeDispose(fn: () => void) { if (activeEffectScope) { activeEffectScope.cleanups.push(fn) } else if (__DEV__) { warn( `onScopeDispose() is called when there is no active effect scope` + ` to be associated with.` ) } } |