wip: suspense ideas
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user