wip: suspense buffer effects

This commit is contained in:
Evan You 2019-09-10 20:53:28 -04:00
parent 42967f1f5a
commit 9ef987830d
2 changed files with 29 additions and 15 deletions

View File

@ -24,7 +24,8 @@ import {
EMPTY_OBJ, EMPTY_OBJ,
EMPTY_ARR, EMPTY_ARR,
isReservedProp, isReservedProp,
isFunction isFunction,
isArray
} from '@vue/shared' } from '@vue/shared'
import { queueJob, queuePostFlushCb, flushPostFlushCbs } from './scheduler' import { queueJob, queuePostFlushCb, flushPostFlushCbs } from './scheduler'
import { import {
@ -77,6 +78,19 @@ function invokeHooks(hooks: Function[], arg?: any) {
} }
} }
function queuePostEffect(
fn: Function | Function[],
suspense: SuspenseBoundary<any, any> | null
) {
if (suspense === null) {
queuePostFlushCb(fn)
} else if (isArray(fn)) {
suspense.effects.push(...fn)
} else {
suspense.effects.push(fn)
}
}
export interface RendererOptions<HostNode = any, HostElement = any> { export interface RendererOptions<HostNode = any, HostElement = any> {
patchProp( patchProp(
el: HostElement, el: HostElement,
@ -341,9 +355,9 @@ export function createRenderer<
} }
hostInsert(el, container, anchor) hostInsert(el, container, anchor)
if (props != null && props.vnodeMounted != null) { if (props != null && props.vnodeMounted != null) {
queuePostFlushCb(() => { queuePostEffect(() => {
invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode) invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode)
}) }, parentSuspense)
} }
} }
@ -492,9 +506,9 @@ export function createRenderer<
} }
if (newProps.vnodeUpdated != null) { if (newProps.vnodeUpdated != null) {
queuePostFlushCb(() => { queuePostEffect(() => {
invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1) invokeDirectiveHook(newProps.vnodeUpdated, parentComponent, n2, n1)
}) }, parentSuspense)
} }
} }
@ -682,7 +696,7 @@ export function createRenderer<
)) ))
function resolveSuspense() { function resolveSuspense() {
const { subTree, fallbackTree, bufferedJobs, vnode } = suspense const { subTree, fallbackTree, effects, vnode } = suspense
// unmount fallback tree // unmount fallback tree
unmount(fallbackTree as HostVNode, parentComponent, suspense, true) unmount(fallbackTree as HostVNode, parentComponent, suspense, true)
// move content from off-dom container to actual container // move content from off-dom container to actual container
@ -700,14 +714,14 @@ export function createRenderer<
if (!parent.isResolved) { if (!parent.isResolved) {
// found a pending parent suspense, merge buffered post jobs // found a pending parent suspense, merge buffered post jobs
// into that parent // into that parent
parent.bufferedJobs.push(...bufferedJobs) parent.effects.push(...effects)
hasUnresolvedAncestor = true hasUnresolvedAncestor = true
break break
} }
} }
// no pending parent suspense, flush all jobs // no pending parent suspense, flush all jobs
if (!hasUnresolvedAncestor) { if (!hasUnresolvedAncestor) {
queuePostFlushCb(bufferedJobs) queuePostFlushCb(effects)
} }
suspense.isResolved = true suspense.isResolved = true
// invoke @resolve event // invoke @resolve event
@ -949,7 +963,7 @@ export function createRenderer<
initialVNode.el = subTree.el initialVNode.el = subTree.el
// mounted hook // mounted hook
if (instance.m !== null) { if (instance.m !== null) {
queuePostFlushCb(instance.m) queuePostEffect(instance.m, parentSuspense)
} }
mounted = true mounted = true
} else { } else {
@ -1002,7 +1016,7 @@ export function createRenderer<
} }
// upated hook // upated hook
if (instance.u !== null) { if (instance.u !== null) {
queuePostFlushCb(instance.u) queuePostEffect(instance.u, parentSuspense)
} }
if (__DEV__) { if (__DEV__) {
@ -1484,9 +1498,9 @@ export function createRenderer<
} }
if (props != null && props.vnodeUnmounted != null) { if (props != null && props.vnodeUnmounted != null) {
queuePostFlushCb(() => { queuePostEffect(() => {
invokeDirectiveHook(props.vnodeUnmounted, parentComponent, vnode) invokeDirectiveHook(props.vnodeUnmounted, parentComponent, vnode)
}) }, parentSuspense)
} }
} }
@ -1509,7 +1523,7 @@ export function createRenderer<
unmount(subTree, instance, parentSuspense, doRemove) unmount(subTree, instance, parentSuspense, doRemove)
// unmounted hook // unmounted hook
if (um !== null) { if (um !== null) {
queuePostFlushCb(um) queuePostEffect(um, parentSuspense)
} }
} }

View File

@ -18,7 +18,7 @@ export interface SuspenseBoundary<
oldFallbackTree: HostVNode | null oldFallbackTree: HostVNode | null
deps: number deps: number
isResolved: boolean isResolved: boolean
bufferedJobs: Function[] effects: Function[]
resolve(): void resolve(): void
} }
@ -38,7 +38,7 @@ export function createSuspenseBoundary<HostNode, HostElement>(
fallbackTree: null, fallbackTree: null,
oldFallbackTree: null, oldFallbackTree: null,
isResolved: false, isResolved: false,
bufferedJobs: [], effects: [],
resolve resolve
} }
} }