File tree 3 files changed +45
-3
lines changed
3 files changed +45
-3
lines changed Original file line number Diff line number Diff line change 1
- import { queueJob , nextTick , queuePostFlushCb } from '../src/scheduler'
1
+ import {
2
+ queueJob ,
3
+ nextTick ,
4
+ queuePostFlushCb ,
5
+ invalidateJob
6
+ } from '../src/scheduler'
2
7
3
8
describe ( 'scheduler' , ( ) => {
4
9
it ( 'nextTick' , async ( ) => {
@@ -230,4 +235,23 @@ describe('scheduler', () => {
230
235
expect ( calls ) . toEqual ( [ 'job1' , 'job2' , 'cb1' , 'cb2' ] )
231
236
} )
232
237
} )
238
+
239
+ test ( 'invalidateJob' , async ( ) => {
240
+ const calls : string [ ] = [ ]
241
+ const job1 = ( ) => {
242
+ calls . push ( 'job1' )
243
+ invalidateJob ( job2 )
244
+ job2 ( )
245
+ }
246
+ const job2 = ( ) => {
247
+ calls . push ( 'job2' )
248
+ }
249
+ // queue both jobs
250
+ queueJob ( job1 )
251
+ queueJob ( job2 )
252
+ expect ( calls ) . toEqual ( [ ] )
253
+ await nextTick ( )
254
+ // job2 should be called only once
255
+ expect ( calls ) . toEqual ( [ 'job1' , 'job2' ] )
256
+ } )
233
257
} )
Original file line number Diff line number Diff line change @@ -30,7 +30,12 @@ import {
30
30
isFunction ,
31
31
PatchFlags
32
32
} from '@vue/shared'
33
- import { queueJob , queuePostFlushCb , flushPostFlushCbs } from './scheduler'
33
+ import {
34
+ queueJob ,
35
+ queuePostFlushCb ,
36
+ flushPostFlushCbs ,
37
+ invalidateJob
38
+ } from './scheduler'
34
39
import {
35
40
effect ,
36
41
stop ,
@@ -895,6 +900,9 @@ export function createRenderer<
895
900
} else {
896
901
// normal update
897
902
instance . next = n2
903
+ // in case the child component is also queued, remove it to avoid
904
+ // double updating the same child component in the same flush.
905
+ invalidateJob ( instance . update )
898
906
// instance.update is the reactive effect runner.
899
907
instance . update ( )
900
908
}
Original file line number Diff line number Diff line change 1
1
import { ErrorCodes , callWithErrorHandling } from './errorHandling'
2
2
import { isArray } from '@vue/shared'
3
3
4
- const queue : Function [ ] = [ ]
4
+ const queue : ( Function | null ) [ ] = [ ]
5
5
const postFlushCbs : Function [ ] = [ ]
6
6
const p = Promise . resolve ( )
7
7
@@ -22,6 +22,13 @@ export function queueJob(job: () => void) {
22
22
}
23
23
}
24
24
25
+ export function invalidateJob ( job : ( ) => void ) {
26
+ const i = queue . indexOf ( job )
27
+ if ( i > - 1 ) {
28
+ queue [ i ] = null
29
+ }
30
+ }
31
+
25
32
export function queuePostFlushCb ( cb : Function | Function [ ] ) {
26
33
if ( ! isArray ( cb ) ) {
27
34
postFlushCbs . push ( cb )
@@ -64,6 +71,9 @@ function flushJobs(seen?: CountMap) {
64
71
seen = seen || new Map ( )
65
72
}
66
73
while ( ( job = queue . shift ( ) ) ) {
74
+ if ( job === null ) {
75
+ continue
76
+ }
67
77
if ( __DEV__ ) {
68
78
checkRecursiveUpdates ( seen ! , job )
69
79
}
You can’t perform that action at this time.
0 commit comments