1
1
import { ErrorCodes , callWithErrorHandling } from './errorHandling'
2
2
import { isArray } from '@vue/shared'
3
3
import { ComponentPublicInstance } from './componentPublicInstance'
4
+ import { ComponentInternalInstance , getComponentName } from './component'
5
+ import { warn } from './warning'
4
6
5
7
export interface SchedulerJob {
6
8
( ) : void
@@ -22,6 +24,7 @@ export interface SchedulerJob {
22
24
* stabilizes (#1727).
23
25
*/
24
26
allowRecurse ?: boolean
27
+ ownerInstance ?: ComponentInternalInstance
25
28
}
26
29
27
30
export type SchedulerCb = Function & { id ?: number }
@@ -164,8 +167,11 @@ export function flushPreFlushCbs(
164
167
preFlushIndex < activePreFlushCbs . length ;
165
168
preFlushIndex ++
166
169
) {
167
- if ( __DEV__ ) {
170
+ if (
171
+ __DEV__ &&
168
172
checkRecursiveUpdates ( seen ! , activePreFlushCbs [ preFlushIndex ] )
173
+ ) {
174
+ continue
169
175
}
170
176
activePreFlushCbs [ preFlushIndex ] ( )
171
177
}
@@ -200,8 +206,11 @@ export function flushPostFlushCbs(seen?: CountMap) {
200
206
postFlushIndex < activePostFlushCbs . length ;
201
207
postFlushIndex ++
202
208
) {
203
- if ( __DEV__ ) {
209
+ if (
210
+ __DEV__ &&
204
211
checkRecursiveUpdates ( seen ! , activePostFlushCbs [ postFlushIndex ] )
212
+ ) {
213
+ continue
205
214
}
206
215
activePostFlushCbs [ postFlushIndex ] ( )
207
216
}
@@ -235,8 +244,8 @@ function flushJobs(seen?: CountMap) {
235
244
for ( flushIndex = 0 ; flushIndex < queue . length ; flushIndex ++ ) {
236
245
const job = queue [ flushIndex ]
237
246
if ( job ) {
238
- if ( __DEV__ ) {
239
- checkRecursiveUpdates ( seen ! , job )
247
+ if ( __DEV__ && checkRecursiveUpdates ( seen ! , job ) ) {
248
+ continue
240
249
}
241
250
callWithErrorHandling ( job , null , ErrorCodes . SCHEDULER )
242
251
}
@@ -263,13 +272,18 @@ function checkRecursiveUpdates(seen: CountMap, fn: SchedulerJob | SchedulerCb) {
263
272
} else {
264
273
const count = seen . get ( fn ) !
265
274
if ( count > RECURSION_LIMIT ) {
266
- throw new Error (
267
- `Maximum recursive updates exceeded. ` +
275
+ const instance = ( fn as SchedulerJob ) . ownerInstance
276
+ const componentName = instance && getComponentName ( instance . type )
277
+ warn (
278
+ `Maximum recursive updates exceeded${
279
+ componentName ? ` in component <${ componentName } >` : ``
280
+ } . ` +
268
281
`This means you have a reactive effect that is mutating its own ` +
269
282
`dependencies and thus recursively triggering itself. Possible sources ` +
270
283
`include component template, render function, updated hook or ` +
271
284
`watcher source function.`
272
285
)
286
+ return true
273
287
} else {
274
288
seen . set ( fn , count + 1 )
275
289
}
0 commit comments