const hooks: Function[] = []
- function queueHook(fn: Function) {
- hooks.push(fn)
- }
-
function flushHooks() {
let fn
while ((fn = hooks.shift())) {
}
function mountRef(ref: Ref, el: RenderNode | MountedComponent) {
- queueHook(() => {
+ hooks.push(() => {
ref(el)
})
}
}
},
{
- scheduler: queueUpdate
- // TODO add API for using onTrigger for component re-render debugging
+ scheduler: queueUpdate,
+ onTrack: instance.renderTracked,
+ onTrigger: instance.renderTriggered
}
)
mountRef(ref, instance)
}
if (instance.mounted) {
- queueHook(() => {
+ hooks.push(() => {
;(instance as any).mounted.call(instance.$proxy)
})
}
}
if (instance.updated) {
- queueHook(() => {
+ // Because the child's update is executed by the scheduler and not
+ // synchronously within the parent's update call, the child's updated hook
+ // will be added to the queue AFTER the parent's, but they should be
+ // invoked BEFORE the parent's. Therefore we add them to the head of the
+ // queue instead.
+ hooks.unshift(() => {
;(instance as any).updated.call(instance.$proxy, nextVNode)
})
}
calls.push('job1')
// job1 queues job2
queueJob(job2)
- // should be called sync
- expect(calls).toEqual(['job1', 'job2'])
}
const job2 = () => {
calls.push('job2')
calls.push('job1')
// job1 queues job2
queueJob(job2, cb2)
- // should be called sync
- expect(calls).toEqual(['job1', 'job2'])
}
const job2 = () => {
calls.push('job2')
const postFlushCbs: Array<() => void> = []
const p = Promise.resolve()
-let flushing = false
+let hasPendingFlush = false
export function nextTick(fn?: () => void): Promise<void> {
return p.then(fn)
export function queueJob(job: () => void, postFlushCb?: () => void) {
if (queue.indexOf(job) === -1) {
- if (flushing) {
- job()
- } else {
- queue.push(job)
+ queue.push(job)
+ if (!hasPendingFlush) {
+ hasPendingFlush = true
+ nextTick(flushJobs)
}
}
- if (postFlushCb) {
+ if (postFlushCb && postFlushCbs.indexOf(postFlushCb) === -1) {
postFlushCbs.push(postFlushCb)
}
- if (!flushing) {
- nextTick(flushJobs)
- }
}
function flushJobs() {
- flushing = true
let job
while ((job = queue.shift())) {
job()
while ((job = postFlushCbs.shift())) {
job()
}
- flushing = false
+ hasPendingFlush = false
}