wip: suspense ideas

This commit is contained in:
Evan You
2019-09-07 11:28:40 -04:00
parent a45d9567df
commit 8b3aa60a18
3 changed files with 113 additions and 2 deletions

View File

@@ -5,12 +5,14 @@ import {
Portal,
normalizeVNode,
VNode,
VNodeChildren
VNodeChildren,
Suspense
} from './vnode'
import {
ComponentInternalInstance,
createComponentInstance,
setupStatefulComponent
setupStatefulComponent,
setCurrentInstance
} from './component'
import {
renderComponentRoot,
@@ -40,6 +42,12 @@ import { pushWarningContext, popWarningContext, warn } from './warning'
import { invokeDirectiveHook } from './directives'
import { ComponentPublicInstance } from './componentPublicInstanceProxy'
import { App, createAppAPI } from './apiApp'
import {
SuspenseSymbol,
createSuspenseBoundary,
SuspenseBoundary
} from './suspense'
import { provide } from './apiInject'
const prodEffectOptions = {
scheduler: queueJob
@@ -187,6 +195,17 @@ export function createRenderer<
optimized
)
break
case Suspense:
processSuspense(
n1,
n2,
container,
anchor,
parentComponent,
isSVG,
optimized
)
break
default:
if (shapeFlag & ShapeFlags.ELEMENT) {
processElement(
@@ -575,6 +594,44 @@ export function createRenderer<
processEmptyNode(n1, n2, container, anchor)
}
function processSuspense(
n1: HostVNode | null,
n2: HostVNode,
container: HostElement,
anchor: HostNode | null,
parentComponent: ComponentInternalInstance | null,
isSVG: boolean,
optimized: boolean
) {
if (n1 == null) {
const parentSuspense =
parentComponent &&
(parentComponent.provides[SuspenseSymbol as any] as SuspenseBoundary)
const suspense = (n2.suspense = createSuspenseBoundary(parentSuspense))
// provide this as the parent suspense for descendents
setCurrentInstance(parentComponent)
provide(SuspenseSymbol, suspense)
setCurrentInstance(null)
// start mounting the subtree off-dom
// - tracking async deps and buffering postQueue jobs on current boundary
// now check if we have encountered any async deps
// yes: mount the fallback tree.
// Each time an async dep resolves, it pings the boundary
// and causes a re-entry.
// no: just mount the tree
// - if have parent boundary that is still not resolved:
// merge the buffered jobs into parent
// - else: flush buffered jobs.
// - mark resolved.
} else {
const suspense = (n2.suspense = n1.suspense) as SuspenseBoundary
}
}
function processComponent(
n1: HostVNode | null,
n2: HostVNode,