]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: retry suspense async deps from resolved dep instead of root
authorEvan You <yyx990803@gmail.com>
Tue, 10 Sep 2019 14:09:04 +0000 (10:09 -0400)
committerEvan You <yyx990803@gmail.com>
Wed, 11 Sep 2019 15:10:13 +0000 (11:10 -0400)
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/suspense.ts

index 45ba646b1e878c3dd3880181de107e945b6c1431..7ea13d9409268419aeeb38f15c0d349ba5ce127a 100644 (file)
@@ -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 {
index bbe5b0928a7c66ccf3f74e4bcdc7da8e10a308b3..f5f2f84bee95252e9665b7c7e7f3dfd7ec3e5e93 100644 (file)
@@ -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<HostNode, HostElement>(
   vnode: VNode<HostNode, HostElement>,
-  parent: SuspenseBoundary<HostNode, HostElement> | null
+  parent: SuspenseBoundary<HostNode, HostElement> | null,
+  retry: () => void,
+  resolve: () => void
 ): SuspenseBoundary<HostNode, HostElement> {
-  let retry: Function
-  let resolve: Function
-  const suspense: SuspenseBoundary<HostNode, HostElement> = {
+  return {
     vnode,
     parent,
     deps: 0,
@@ -38,19 +36,7 @@ export function createSuspenseBoundary<HostNode, HostElement>(
     oldFallbackTree: null,
     isResolved: false,
     bufferedJobs: [],
-    onRetry(fn: Function) {
-      retry = fn
-    },
-    retry() {
-      retry()
-    },
-    onResolve(fn: Function) {
-      resolve = fn
-    },
-    resolve() {
-      resolve()
-    }
+    retry,
+    resolve
   }
-
-  return suspense
 }