Skip to content

Commit c2dad4b

Browse files
committed
refactor(reactivity): combine notify() and scheduler() in ReactiveEffect
1 parent 78d56d1 commit c2dad4b

File tree

5 files changed

+43
-47
lines changed

5 files changed

+43
-47
lines changed

packages/reactivity/src/effect.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ export class ReactiveEffect<T = any>
9292
}
9393

9494
pause(): void {
95-
if (!(this.flags & EffectFlags.PAUSED)) {
96-
this.flags |= EffectFlags.PAUSED
97-
}
95+
this.flags |= EffectFlags.PAUSED
9896
}
9997

10098
resume(): void {
@@ -105,14 +103,7 @@ export class ReactiveEffect<T = any>
105103
}
106104

107105
notify(): void {
108-
const flags = this.flags
109-
if (!(flags & EffectFlags.PAUSED)) {
110-
this.scheduler()
111-
}
112-
}
113-
114-
scheduler(): void {
115-
if (this.dirty) {
106+
if (!(this.flags & EffectFlags.PAUSED) && this.dirty) {
116107
this.run()
117108
}
118109
}
@@ -197,15 +188,23 @@ export function effect<T = any>(
197188

198189
const e = new ReactiveEffect(fn)
199190
if (options) {
200-
const onStop = options.onStop
201-
if (onStop !== undefined) {
191+
const { onStop, scheduler } = options
192+
if (onStop) {
202193
options.onStop = undefined
203194
const stop = e.stop.bind(e)
204195
e.stop = () => {
205196
stop()
206197
onStop()
207198
}
208199
}
200+
if (scheduler) {
201+
options.scheduler = undefined
202+
e.notify = () => {
203+
if (!(e.flags & EffectFlags.PAUSED)) {
204+
scheduler()
205+
}
206+
}
207+
}
209208
extend(e, options)
210209
}
211210
try {

packages/reactivity/src/watch.ts

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -214,21 +214,22 @@ export class WatcherEffect extends ReactiveEffect {
214214
}
215215
}
216216

217-
scheduler(): void {
218-
if (!this.dirty) {
217+
run(initialRun = false): void {
218+
const oldValue = this.oldValue
219+
const newValue = (this.oldValue = super.run())
220+
if (!this.cb) {
219221
return
220222
}
221-
const newValue = this.run()
222-
if (!this.cb) {
223+
const { immediate, deep, call } = this.options
224+
if (initialRun && !immediate) {
223225
return
224226
}
225-
const { deep, call } = this.options
226227
if (
227228
deep ||
228229
this.forceTrigger ||
229230
(this.isMultiSource
230-
? (newValue as any[]).some((v, i) => hasChanged(v, this.oldValue[i]))
231-
: hasChanged(newValue, this.oldValue))
231+
? (newValue as any[]).some((v, i) => hasChanged(v, oldValue[i]))
232+
: hasChanged(newValue, oldValue))
232233
) {
233234
// cleanup before running cb again
234235
cleanup(this)
@@ -238,18 +239,17 @@ export class WatcherEffect extends ReactiveEffect {
238239
const args = [
239240
newValue,
240241
// pass undefined as the old value when it's changed for the first time
241-
this.oldValue === INITIAL_WATCHER_VALUE
242+
oldValue === INITIAL_WATCHER_VALUE
242243
? undefined
243-
: this.isMultiSource && this.oldValue[0] === INITIAL_WATCHER_VALUE
244+
: this.isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE
244245
? []
245-
: this.oldValue,
246+
: oldValue,
246247
this.boundCleanup,
247248
]
248249
call
249250
? call(this.cb, WatchErrorCodes.WATCH_CALLBACK, args)
250251
: // @ts-expect-error
251252
this.cb(...args)
252-
this.oldValue = newValue
253253
} finally {
254254
activeWatcher = currentWatcher
255255
}
@@ -283,16 +283,7 @@ export function watch(
283283
): WatchHandle {
284284
const effect = new WatcherEffect(source, cb, options)
285285

286-
// initial run
287-
if (cb) {
288-
if (options.immediate) {
289-
effect.scheduler()
290-
} else {
291-
effect.oldValue = effect.run()
292-
}
293-
} else {
294-
effect.run()
295-
}
286+
effect.run(true)
296287

297288
const stop = effect.stop.bind(effect) as WatchHandle
298289
stop.pause = effect.pause.bind(effect)

packages/runtime-core/src/apiWatch.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ class RenderWatcherEffect extends WatcherEffect {
160160
this.flags |= EffectFlags.ALLOW_RECURSE
161161
}
162162

163-
const job: SchedulerJob = this.scheduler.bind(this)
163+
const job: SchedulerJob = () => {
164+
if (this.dirty) {
165+
this.run()
166+
}
167+
}
164168
// important: mark the job as a watcher callback so that scheduler knows
165169
// it is allowed to self-trigger (#1727)
166170
if (cb) {
@@ -184,8 +188,8 @@ class RenderWatcherEffect extends WatcherEffect {
184188
)
185189
} else if (flush === 'pre') {
186190
queueJob(this.job, this.instance ? this.instance.uid : undefined, true)
187-
} else {
188-
this.scheduler()
191+
} else if (this.dirty) {
192+
this.run()
189193
}
190194
}
191195
}
@@ -253,15 +257,11 @@ function doWatch(
253257

254258
// initial run
255259
if (cb) {
256-
if (options.immediate) {
257-
effect.scheduler()
258-
} else {
259-
effect.oldValue = effect.run()
260-
}
260+
effect.run(true)
261261
} else if (flush === 'post') {
262262
queuePostRenderEffect(effect.job, undefined, instance && instance.suspense)
263263
} else {
264-
effect.scheduler()
264+
effect.run(true)
265265
}
266266

267267
const stop = effect.stop.bind(effect) as WatchHandle

packages/runtime-core/src/renderer.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,9 +1358,11 @@ function baseCreateRenderer(
13581358
}
13591359
}
13601360

1361-
scheduler() {
1362-
const job = this.job
1363-
queueJob(job, job.i!.uid)
1361+
notify(): void {
1362+
if (!(this.flags & EffectFlags.PAUSED)) {
1363+
const job = this.job
1364+
queueJob(job, job.i!.uid)
1365+
}
13641366
}
13651367

13661368
fn() {

packages/runtime-vapor/src/renderEffect.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ class RenderEffect extends ReactiveEffect {
2323
warn('renderEffect called without active EffectScope or Vapor instance.')
2424
}
2525

26-
const job: SchedulerJob = super.scheduler.bind(this)
26+
const job: SchedulerJob = () => {
27+
if (this.dirty) {
28+
this.run()
29+
}
30+
}
2731
this.updateJob = () => {
2832
instance!.isUpdating = false
2933
instance!.u && invokeArrayFns(instance!.u)

0 commit comments

Comments
 (0)