Skip to content

Commit 9bfc50a

Browse files
committed
resolve async components in parallel
1 parent ac518de commit 9bfc50a

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

src/history/base.js

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -276,32 +276,52 @@ function poll (
276276
}
277277
}
278278

279-
function resolveAsyncComponents (matched: Array<RouteRecord>): Array<?Function> {
280-
return flatMapComponents(matched, (def, _, match, key) => {
281-
// if it's a function and doesn't have Vue options attached,
279+
function resolveAsyncComponents (matched: Array<RouteRecord>): Function {
280+
let _next
281+
let pending = 0
282+
let rejected = false
283+
284+
flatMapComponents(matched, (def, _, match, key) => {
285+
// if it's a function and doesn't have cid attached,
282286
// assume it's an async component resolve function.
283287
// we are not using Vue's default async resolving mechanism because
284288
// we want to halt the navigation until the incoming component has been
285289
// resolved.
286-
if (typeof def === 'function' && !def.options) {
287-
return (to, from, next) => {
288-
const resolve = once(resolvedDef => {
289-
match.components[key] = resolvedDef
290-
next()
291-
})
290+
if (typeof def === 'function' && def.cid === undefined) {
291+
pending++
292292

293-
const reject = once(reason => {
294-
warn(false, `Failed to resolve async component ${key}: ${reason}`)
295-
next(false)
296-
})
293+
const resolve = once(resolvedDef => {
294+
match.components[key] = resolvedDef
295+
pending--
296+
if (pending <= 0 && _next) {
297+
_next()
298+
}
299+
})
297300

298-
const res = def(resolve, reject)
299-
if (res && typeof res.then === 'function') {
300-
res.then(resolve, reject)
301+
const reject = once(reason => {
302+
warn(false, `Failed to resolve async component ${key}: ${reason}`)
303+
if (!rejected) {
304+
rejected = true
305+
if (_next) _next(false)
301306
}
307+
})
308+
309+
const res = def(resolve, reject)
310+
if (res && typeof res.then === 'function') {
311+
res.then(resolve, reject)
302312
}
303313
}
304314
})
315+
316+
return (to, from, next) => {
317+
if (rejected) {
318+
next(false)
319+
} else if (pending <= 0) {
320+
next()
321+
} else {
322+
_next = next
323+
}
324+
}
305325
}
306326

307327
function flatMapComponents (

0 commit comments

Comments
 (0)