Skip to content

Commit 7954d9d

Browse files
feat: u
1 parent b8284d1 commit 7954d9d

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

src/core/observer/scheduler.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ if (inBrowser && !isIE) {
6767

6868
/**
6969
* Flush both queues and run the watchers.
70+
* 刷新队列并运行观察程序
7071
*/
7172
function flushSchedulerQueue () {
7273
currentFlushTimestamp = getNow()
@@ -81,10 +82,17 @@ function flushSchedulerQueue () {
8182
// user watchers are created before the render watcher)
8283
// 3. If a component is destroyed during a parent component's watcher run,
8384
// its watchers can be skipped.
85+
// 刷新前排序队列
86+
// 这样做确保了:
87+
// 1、组件的更新顺序始终是从父组件到子组件(因为父组件总是比子组件先创建)
88+
// 2、组件内用户创建的watcher比组件自身的render watcher先运行(因为用户的watcher比render watcher先创建)
89+
// 3、如果组件在父组件的watcher运行的时候被销毁,该组件的watcher会被跳过
90+
// TODO 写一篇[].sort使用注意事项
8491
queue.sort((a, b) => a.id - b.id)
8592

8693
// do not cache length because more watchers might be pushed
8794
// as we run existing watchers
95+
// 不要缓存队列的length属性,因为当我们运行已存在的watcher时,可能会有更多的watcher被加入到队列中
8896
for (index = 0; index < queue.length; index++) {
8997
watcher = queue[index]
9098
if (watcher.before) {
@@ -94,6 +102,7 @@ function flushSchedulerQueue () {
94102
has[id] = null
95103
watcher.run()
96104
// in dev build, check and stop circular updates.
105+
// 在开发环境中,检查并停止陷入死循环的更新
97106
if (process.env.NODE_ENV !== 'production' && has[id] != null) {
98107
circular[id] = (circular[id] || 0) + 1
99108
if (circular[id] > MAX_UPDATE_COUNT) {

src/core/util/next-tick.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ function flushCallbacks () {
3030
// where microtasks have too high a priority and fire in between supposedly
3131
// sequential events (e.g. #4521, #6690, which have workarounds)
3232
// or even between bubbling of the same event (#6566).
33+
34+
// 这里我们有一个使用microtasks来实现的异步延迟包装器
35+
// 在2.5版本我们使用macrotasks(结合microtasks)
36+
// 然而,如果在重绘前改变了状态,那么这么做会有微妙的问题(例如 #6813 out-in过渡,改变的状态在下一个tick才会生效,导致css先生效,页面闪一下)
37+
// 而且,在事件处理器中使用macrotasks,会导致一些奇怪的行为并且无法规避(例如 #7109, #7153, #7546, #7834, #8109)
38+
// 所以我们再次在各处使用microtasks
39+
// 这种权衡的一个主要缺点是,在某些情况下微任务具有过高的优先级,并且在本应该按顺序发生的事件之间执行,甚至是同一事件源冒泡监听回调之间执行(#6566)
3340
let timerFunc
3441

3542
// The nextTick behavior leverages the microtask queue, which can be accessed
@@ -38,6 +45,11 @@ let timerFunc
3845
// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
3946
// completely stops working after triggering a few times... so, if native
4047
// Promise is available, we will use it:
48+
49+
// nextTick函数的行为,改变了microtask队列。microtask队列可以通过原生的Promise.then或者MutationObserver改变
50+
// MutationObserver有着广泛的支持,然而在iOS >= 9.3.3的UIWebView上,当在触摸事件处理函数上触发MutationObserver时有着严重的bug
51+
// 在触发了几次之后,MutationObserver完全停止了工作
52+
// 所以,如果原生的Promise是可用的,我们将使用原生Promise
4153
/* istanbul ignore next, $flow-disable-line */
4254
if (typeof Promise !== 'undefined' && isNative(Promise)) {
4355
const p = Promise.resolve()

0 commit comments

Comments
 (0)