/* @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)
}
}
}

这个方法主要用来保存watcher形成一个事件队列, 并且调用nextTick 执行watcher的run方法

vue.js 源代码学习笔记 ----- core scedule.js的更多相关文章

  1. vue.js 源代码学习笔记 ----- core array.js

    /* * not type checking this file because flow doesn't play well with * dynamically accessing methods ...

  2. vue.js 源代码学习笔记 ----- core lifecycle

    /* @flow */ import config from '../config' import Watcher from '../observer/watcher' import { mark, ...

  3. node.js day01学习笔记:认识node.js

    Node.js(JavaScript,everywhere) 1.Node.js 介绍 1.1. 为什么要学习Node.js 企业需求 + 具有服务端开发经验更好 + front-end + back ...

  4. vue.js 源代码学习笔记 ----- html-parse.js

    /** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...

  5. vue.js 源代码学习笔记 ----- 工具方法 lang

    /* @flow */ // Object.freeze 使得这个对象不能增加属性, 修改属性, 这样就保证了这个对象在任何时候都是空的 export const emptyObject = Obje ...

  6. vue.js 源代码学习笔记 ----- 工具方法 env

    /* @flow */ /* globals MutationObserver */ import { noop } from 'shared/util' // can we use __proto_ ...

  7. vue.js 源代码学习笔记 ----- 工具方法 share

    /* @flow */ /** * Convert a value to a string that is actually rendered. { .. } [ .. ] 2 => '' */ ...

  8. vue.js 源代码学习笔记 ----- 工具方法 option

    /* @flow */ import Vue from '../instance/index' import config from '../config' import { warn } from ...

  9. vue.js 源代码学习笔记 ----- helpers.js

    /* @flow */ import { parseFilters } from './parser/filter-parser' export function baseWarn (msg: str ...

随机推荐

  1. 在python3下使用OpenCV 抓取摄像头图像提取蓝色

    工作中需要对摄像头进行调试, Python平台大大提高调试效率. 从网找到段代码, 可以从摄像头图像中抠出蓝色. import cv2 import numpy as np cap  = cv2.Vi ...

  2. Django学习笔记之django-debug-toolbar使用指南

    介绍 django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息. github地址 文档地址 安装 pip3 in ...

  3. Tomcat的工作模式和运行模式

    (1)工作模式 Tomcat作为servlet容器,有三种工作模式: 1.独立的servlet容器,servlet容器是web服务器的一部分: 2.进程内的servlet容器,servlet容器是作为 ...

  4. JavaScript校验网址

    JavaScript校验网址 var linkUrl = 'https://www.baidu.com' if( typeof (linkUrl) != undefined && li ...

  5. 【读书笔记】《深入浅出nodejs》第四章 异步编程

    1. 异步编程的基础 -- 函数式编程 (1)高阶函数 -- 是可以把函数作为参数,或是将函数作为返回值的函数. (2)偏函数用法 -- 创建一个调用另外一个部分 -- 参数或变量已经预置的函数 -- ...

  6. .net 数据缓存(一)之介绍

    现在的业务系统越来复杂,大型门户网站内容越来越多,数据库的数据量也越来愈大,所以有了“大数据”这一概念的出现.但是我们都知道当数据库的数据量和访问过于频繁都会影响系统整体性能体验,特别是并发量高的系统 ...

  7. POJ2739解题报告

    2017-09-01 17:04:45 writer:pprp 一开始读错题了,总是想不到,其实不是很难,但是就是心理太着急了,反而浪费了很长时间 /* @param:poj2739 @writer: ...

  8. 教你如何使用理解懒Redis是更好的Redis

    前言 大家都知道 Redis 是单线程的.真正的内行会告诉你,实际上 Redis 并不是完全单线程,因为在执行磁盘上的特定慢操作时会有多线程.目前为止多线程操作绝大部分集中在 I/O 上以至于在不同线 ...

  9. 嵌入式 Web workers

    前言 虽然worker可以将复杂的运算放入单独线程去运算,不阻塞UI线程,但是,由于worker()的构造函数的参数不能读取本地的文件,只能来自网络,所以当在一个项目里想使用本地的模块函数,是一个很麻 ...

  10. 尽量不要使用using namespace std

    C++标准程序库中的所有标识符都被定义于一个名为std的namespace中. namespace是指标识符的各种可见范围.命名空间用关键字namespace 来定义.命名空间是C++的一种机制,用来 ...