vue.js源代码core scedule.js学习笔记

vue.js 源代码学习笔记 core scedule.js,供大家参考,具体内容如下

/* @flow */

import type Watcher from './watcher'

import config from '../config'

import { callHook } from '../instance/lifecycle'

import {

warn,

nextTick,

devtools

} from '../util/index'

const queue: Array<Watcher> = []

let has: { [key: number]: ?true } = {}

let circular: { [key: number]: number } = {}

let waiting = false

let flushing = false

let index = 0

/**

* Reset the scheduler's state.

*/

function resetSchedulerState () {

queue.length = 0

has = {}

if (process.env.NODE_ENV !== 'production') {

circular = {}

}

waiting = flushing = false

}

/**

* Flush both queues and run the watchers.

*/

function flushSchedulerQueue () {

flushing = true

let watcher, id, vm

// Sort queue before flush.

// This ensures that:

// 1. Components are updated from parent to child. (because parent is always

// created before the child)

// 2. A component's user watchers are run before its render watcher (because

// user watchers are created before the render watcher)

// 3. If a component is destroyed during a parent component's watcher run,

// its watchers can be skipped.

queue.sort((a, b) => a.id - b.id)

// do not cache length because more watchers might be pushed

// as we run existing watchers

for (index = 0; index < queue.length; index++) {

watcher = queue[index]

id = watcher.id

has[id] = null

watcher.run()

// in dev build, check and stop circular updates.

if (process.env.NODE_ENV !== 'production' && has[id] != null) {

circular[id] = (circular[id] || 0) + 1

if (circular[id] > config._maxUpdateCount) {

warn(

'You may have an infinite update loop ' + (

watcher.user

? `in watcher with expression "${watcher.expression}"`

: `in a component render function.`

),

watcher.vm

)

break

}

}

}

// reset scheduler before updated hook called

const oldQueue = queue.slice()

resetSchedulerState()

// call updated hooks

index = oldQueue.length

while (index--) {

watcher = oldQueue[index]

vm = watcher.vm

if (vm._watcher === watcher && vm._isMounted) {

callHook(vm, 'updated')

}

}

// devtool hook

/* istanbul ignore if */

if (devtools && config.devtools) {

devtools.emit('flush')

}

}

/**

* Push a watcher into the watcher queue.

* Jobs with duplicate IDs will be skipped unless it's

* pushed when the queue is being flushed.

*/

export function queueWatcher (watcher: Watcher) {

const id = watcher.id

if (has[id] == null) {

has[id] = true

if (!flushing) {

queue.push(watcher)

} else {

// if already flushing, splice the watcher based on its id

// if already past its id, it will be run next immediately.

let i = queue.length - 1

while (i >= 0 && queue[i].id > watcher.id) {

i--

}

queue.splice(Math.max(i, index) + 1, 0, watcher)

}

// queue the flush

if (!waiting) {

waiting = true

nextTick(flushSchedulerQueue)

}

}

}

以上是 vue.js源代码core scedule.js学习笔记 的全部内容, 来源链接: utcz.com/z/319658.html

回到顶部