From c9e625864a607313abd32a4afffc7affd3d8998e Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 Sep 2019 10:09:04 -0400 Subject: [PATCH] wip: retry suspense async deps from resolved dep instead of root --- packages/runtime-core/src/createRenderer.ts | 45 ++++++++++----------- packages/runtime-core/src/suspense.ts | 26 +++--------- 2 files changed, 27 insertions(+), 44 deletions(-) diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index 45ba646b..7ea13d94 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -610,12 +610,8 @@ export function createRenderer< ) { if (n1 == null) { const contentContainer = hostCreateElement('div') - const suspense = (n2.suspense = createSuspenseBoundary( - n2, - parentSuspense - )) - suspense.onRetry(() => { + function retry() { processFragment( suspense.oldSubTree, suspense.subTree as HostVNode, @@ -631,9 +627,9 @@ export function createRenderer< } else { suspense.resolve() } - }) + } - suspense.onResolve(() => { + function resolve() { // unmount fallback tree unmount(suspense.fallbackTree as HostVNode, parentComponent, true) // move content from off-dom container to actual container @@ -656,7 +652,14 @@ export function createRenderer< queuePostFlushCb(suspense.bufferedJobs) } suspense.isResolved = true - }) + } + + const suspense = (n2.suspense = createSuspenseBoundary( + n2, + parentSuspense, + retry, + resolve + )) // TODO pass it down as an arg instead if (parentComponent) { @@ -749,17 +752,7 @@ export function createRenderer< return } - // a resolved async component, on successful re-entry. - // 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) - ) { + if (shouldUpdateComponent(n1, n2, optimized)) { // normal update instance.next = n2 instance.update() @@ -814,11 +807,15 @@ export function createRenderer< throw new Error('Async component without a suspense boundary!') } suspense.deps++ - instance.asyncDep.then(res => { - instance.asyncResolved = true - handleSetupResult(instance, res) + instance.asyncDep.then(asyncSetupResult => { 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 const placeholder = (instance.subTree = createVNode(Empty)) @@ -1276,7 +1273,7 @@ export function createRenderer< hostInsert(vnode.el as HostNode, container, anchor) const children = vnode.children as HostVNode[] 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) } else { diff --git a/packages/runtime-core/src/suspense.ts b/packages/runtime-core/src/suspense.ts index bbe5b092..f5f2f84b 100644 --- a/packages/runtime-core/src/suspense.ts +++ b/packages/runtime-core/src/suspense.ts @@ -16,19 +16,17 @@ export interface SuspenseBoundary< deps: number isResolved: boolean bufferedJobs: Function[] - onRetry(fn: Function): void retry(): void - onResolve(fn: Function): void resolve(): void } export function createSuspenseBoundary( vnode: VNode, - parent: SuspenseBoundary | null + parent: SuspenseBoundary | null, + retry: () => void, + resolve: () => void ): SuspenseBoundary { - let retry: Function - let resolve: Function - const suspense: SuspenseBoundary = { + return { vnode, parent, deps: 0, @@ -38,19 +36,7 @@ export function createSuspenseBoundary( oldFallbackTree: null, isResolved: false, bufferedJobs: [], - onRetry(fn: Function) { - retry = fn - }, - retry() { - retry() - }, - onResolve(fn: Function) { - resolve = fn - }, - resolve() { - resolve() - } + retry, + resolve } - - return suspense }