wip: retry suspense async deps from resolved dep instead of root
This commit is contained in:
parent
0d176ebf2a
commit
c9e625864a
@ -610,12 +610,8 @@ export function createRenderer<
|
|||||||
) {
|
) {
|
||||||
if (n1 == null) {
|
if (n1 == null) {
|
||||||
const contentContainer = hostCreateElement('div')
|
const contentContainer = hostCreateElement('div')
|
||||||
const suspense = (n2.suspense = createSuspenseBoundary(
|
|
||||||
n2,
|
|
||||||
parentSuspense
|
|
||||||
))
|
|
||||||
|
|
||||||
suspense.onRetry(() => {
|
function retry() {
|
||||||
processFragment(
|
processFragment(
|
||||||
suspense.oldSubTree,
|
suspense.oldSubTree,
|
||||||
suspense.subTree as HostVNode,
|
suspense.subTree as HostVNode,
|
||||||
@ -631,9 +627,9 @@ export function createRenderer<
|
|||||||
} else {
|
} else {
|
||||||
suspense.resolve()
|
suspense.resolve()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
suspense.onResolve(() => {
|
function resolve() {
|
||||||
// unmount fallback tree
|
// unmount fallback tree
|
||||||
unmount(suspense.fallbackTree as HostVNode, parentComponent, true)
|
unmount(suspense.fallbackTree as HostVNode, parentComponent, true)
|
||||||
// move content from off-dom container to actual container
|
// move content from off-dom container to actual container
|
||||||
@ -656,7 +652,14 @@ export function createRenderer<
|
|||||||
queuePostFlushCb(suspense.bufferedJobs)
|
queuePostFlushCb(suspense.bufferedJobs)
|
||||||
}
|
}
|
||||||
suspense.isResolved = true
|
suspense.isResolved = true
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const suspense = (n2.suspense = createSuspenseBoundary(
|
||||||
|
n2,
|
||||||
|
parentSuspense,
|
||||||
|
retry,
|
||||||
|
resolve
|
||||||
|
))
|
||||||
|
|
||||||
// TODO pass it down as an arg instead
|
// TODO pass it down as an arg instead
|
||||||
if (parentComponent) {
|
if (parentComponent) {
|
||||||
@ -749,17 +752,7 @@ export function createRenderer<
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// a resolved async component, on successful re-entry.
|
if (shouldUpdateComponent(n1, n2, optimized)) {
|
||||||
// pickup the mounting process and setup render effect
|
|
||||||
if (!instance.update) {
|
|
||||||
setupRenderEffect(instance, n2, container, anchor, isSVG)
|
|
||||||
} else if (
|
|
||||||
shouldUpdateComponent(n1, n2, optimized) ||
|
|
||||||
// TODO use context suspense
|
|
||||||
(__FEATURE_SUSPENSE__ &&
|
|
||||||
instance.provides.suspense &&
|
|
||||||
!(instance.provides.suspense as any).isResolved)
|
|
||||||
) {
|
|
||||||
// normal update
|
// normal update
|
||||||
instance.next = n2
|
instance.next = n2
|
||||||
instance.update()
|
instance.update()
|
||||||
@ -814,11 +807,15 @@ export function createRenderer<
|
|||||||
throw new Error('Async component without a suspense boundary!')
|
throw new Error('Async component without a suspense boundary!')
|
||||||
}
|
}
|
||||||
suspense.deps++
|
suspense.deps++
|
||||||
instance.asyncDep.then(res => {
|
instance.asyncDep.then(asyncSetupResult => {
|
||||||
instance.asyncResolved = true
|
|
||||||
handleSetupResult(instance, res)
|
|
||||||
suspense.deps--
|
suspense.deps--
|
||||||
suspense.retry()
|
// retry from this component
|
||||||
|
instance.asyncResolved = true
|
||||||
|
handleSetupResult(instance, asyncSetupResult)
|
||||||
|
setupRenderEffect(instance, initialVNode, container, anchor, isSVG)
|
||||||
|
if (suspense.deps === 0) {
|
||||||
|
suspense.resolve()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// give it a placeholder
|
// give it a placeholder
|
||||||
const placeholder = (instance.subTree = createVNode(Empty))
|
const placeholder = (instance.subTree = createVNode(Empty))
|
||||||
@ -1276,7 +1273,7 @@ export function createRenderer<
|
|||||||
hostInsert(vnode.el as HostNode, container, anchor)
|
hostInsert(vnode.el as HostNode, container, anchor)
|
||||||
const children = vnode.children as HostVNode[]
|
const children = vnode.children as HostVNode[]
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
hostInsert(children[i].el as HostNode, container, anchor)
|
move(children[i], container, anchor)
|
||||||
}
|
}
|
||||||
hostInsert(vnode.anchor as HostNode, container, anchor)
|
hostInsert(vnode.anchor as HostNode, container, anchor)
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,19 +16,17 @@ export interface SuspenseBoundary<
|
|||||||
deps: number
|
deps: number
|
||||||
isResolved: boolean
|
isResolved: boolean
|
||||||
bufferedJobs: Function[]
|
bufferedJobs: Function[]
|
||||||
onRetry(fn: Function): void
|
|
||||||
retry(): void
|
retry(): void
|
||||||
onResolve(fn: Function): void
|
|
||||||
resolve(): void
|
resolve(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSuspenseBoundary<HostNode, HostElement>(
|
export function createSuspenseBoundary<HostNode, HostElement>(
|
||||||
vnode: VNode<HostNode, HostElement>,
|
vnode: VNode<HostNode, HostElement>,
|
||||||
parent: SuspenseBoundary<HostNode, HostElement> | null
|
parent: SuspenseBoundary<HostNode, HostElement> | null,
|
||||||
|
retry: () => void,
|
||||||
|
resolve: () => void
|
||||||
): SuspenseBoundary<HostNode, HostElement> {
|
): SuspenseBoundary<HostNode, HostElement> {
|
||||||
let retry: Function
|
return {
|
||||||
let resolve: Function
|
|
||||||
const suspense: SuspenseBoundary<HostNode, HostElement> = {
|
|
||||||
vnode,
|
vnode,
|
||||||
parent,
|
parent,
|
||||||
deps: 0,
|
deps: 0,
|
||||||
@ -38,19 +36,7 @@ export function createSuspenseBoundary<HostNode, HostElement>(
|
|||||||
oldFallbackTree: null,
|
oldFallbackTree: null,
|
||||||
isResolved: false,
|
isResolved: false,
|
||||||
bufferedJobs: [],
|
bufferedJobs: [],
|
||||||
onRetry(fn: Function) {
|
retry,
|
||||||
retry = fn
|
resolve
|
||||||
},
|
|
||||||
retry() {
|
|
||||||
retry()
|
|
||||||
},
|
|
||||||
onResolve(fn: Function) {
|
|
||||||
resolve = fn
|
|
||||||
},
|
|
||||||
resolve() {
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return suspense
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user