vue3-yuanma/packages/runtime-core/src/suspense.ts

49 lines
1.3 KiB
TypeScript
Raw Normal View History

2019-09-09 17:59:53 +00:00
import { VNode } from './vnode'
import { queuePostFlushCb } from './scheduler'
2019-09-07 15:28:40 +00:00
export const SuspenseSymbol = __DEV__ ? Symbol('Suspense key') : Symbol()
2019-09-09 17:59:53 +00:00
export interface SuspenseBoundary<HostNode, HostElement> {
parent: SuspenseBoundary<HostNode, HostElement> | null
contentTree: VNode<HostNode, HostElement> | null
fallbackTree: VNode<HostNode, HostElement> | null
2019-09-07 15:28:40 +00:00
deps: number
isResolved: boolean
2019-09-09 17:59:53 +00:00
bufferedJobs: Function[]
container: HostElement
2019-09-07 15:28:40 +00:00
resolve(): void
}
2019-09-09 17:59:53 +00:00
export function createSuspenseBoundary<HostNode, HostElement>(
parent: SuspenseBoundary<HostNode, HostElement> | null,
container: HostElement
): SuspenseBoundary<HostNode, HostElement> {
const suspense: SuspenseBoundary<HostNode, HostElement> = {
parent,
container,
2019-09-07 15:28:40 +00:00
deps: 0,
2019-09-09 17:59:53 +00:00
contentTree: null,
fallbackTree: null,
2019-09-07 15:28:40 +00:00
isResolved: false,
2019-09-09 17:59:53 +00:00
bufferedJobs: [],
2019-09-07 15:28:40 +00:00
resolve() {
2019-09-09 17:59:53 +00:00
suspense.isResolved = true
let parent = suspense.parent
let hasUnresolvedAncestor = false
while (parent) {
if (!parent.isResolved) {
parent.bufferedJobs.push(...suspense.bufferedJobs)
hasUnresolvedAncestor = true
break
}
}
if (!hasUnresolvedAncestor) {
queuePostFlushCb(suspense.bufferedJobs)
2019-09-07 15:28:40 +00:00
}
2019-09-09 17:59:53 +00:00
suspense.isResolved = true
2019-09-07 15:28:40 +00:00
}
}
2019-09-09 17:59:53 +00:00
return suspense
2019-09-07 15:28:40 +00:00
}