Skip to content

Commit

Permalink
feat: add async option (#8240)
Browse files Browse the repository at this point in the history
This is an option intended only for testing purposes, and should not be used in
application code.
eddyerburgh authored and yyx990803 committed Aug 16, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 833175e commit c944827
Showing 6 changed files with 90 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/core/config.js
Original file line number Diff line number Diff line change
@@ -28,6 +28,9 @@ export type Config = {
getTagNamespace: (x?: string) => string | void;
mustUseProp: (tag: string, type: ?string, name: string) => boolean;

// private
async: boolean;

// legacy
_lifecycleHooks: Array<string>;
};
@@ -114,6 +117,12 @@ export default ({
*/
mustUseProp: no,

/**
* Perform updates asynchronously. Intended to be used by Vue Test Utils
* This will significantly reduce performance if set to false.
*/
async: true,

/**
* Exposed for legacy reasons
*/
7 changes: 7 additions & 0 deletions src/core/observer/dep.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import type Watcher from './watcher'
import { remove } from '../util/index'
import config from '../config'

let uid = 0

@@ -36,6 +37,12 @@ export default class Dep {
notify () {
// stabilize the subscriber list first
const subs = this.subs.slice()
if (process.env.NODE_ENV !== 'production' && !config.async) {
// subs aren't sorted in scheduler if not running async
// we need to sort them now to make sure they fire in correct
// order
subs.sort((a, b) => a.id - b.id)
}
for (let i = 0, l = subs.length; i < l; i++) {
subs[i].update()
}
5 changes: 5 additions & 0 deletions src/core/observer/scheduler.js
Original file line number Diff line number Diff line change
@@ -145,6 +145,11 @@ export function queueWatcher (watcher: Watcher) {
// queue the flush
if (!waiting) {
waiting = true

if (process.env.NODE_ENV !== 'production' && !config.async) {
flushSchedulerQueue()
return
}
nextTick(flushSchedulerQueue)
}
}
67 changes: 67 additions & 0 deletions test/unit/features/global-api/config.spec.js
Original file line number Diff line number Diff line change
@@ -55,4 +55,71 @@ describe('Global config', () => {
Vue.config.ignoredElements = []
})
})

describe('async', () => {
it('does not update synchronously when true', () => {
const spy = jasmine.createSpy()
const vm = new Vue({
template: `<div :class="value"></div>`,
updated: spy,
data: { value: true }
}).$mount()
vm.value = false
expect(spy).not.toHaveBeenCalled()
})

it('updates synchronously when false', () => {
const spy = jasmine.createSpy()
Vue.config.async = false
const vm = new Vue({
template: `<div :class="value"></div>`,
updated: spy,
data: { value: true }
}).$mount()
vm.value = false
expect(spy).toHaveBeenCalled()
Vue.config.async = true
})

it('runs watchers in correct order when false', () => {
Vue.config.async = false
const vm = new Vue({
template: `
<div id="app">
{{ computed }}
</div>`,
props: ['prop'],
propsData: {
'prop': []
},
data: () => ({
data: ''
}),
computed: {
computed () {
return this.prop.join(',')
}
},
watch: {
prop: 'execute'
},
methods: {
execute () {
this.data = this.computed
}
}
}).$mount()
expect(vm.computed).toBe('')
expect(vm.data).toBe('')

vm.prop = [1, 2, 3]
expect(vm.computed).toBe('1,2,3')
expect(vm.data).toBe('1,2,3')

vm.prop.push(4, 5)
expect(vm.computed).toBe('1,2,3,4,5')
expect(vm.data).toBe('1,2,3,4,5')
Vue.config.async = true
})
})
})
1 change: 1 addition & 0 deletions types/test/vue-test.ts
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@ class Test extends Vue {
};
config.keyCodes = { esc: 27 };
config.ignoredElements = ['foo', /^ion-/];
config.async = false
}

static testMethods() {
1 change: 1 addition & 0 deletions types/vue.d.ts
Original file line number Diff line number Diff line change
@@ -74,6 +74,7 @@ export interface VueConfiguration {
warnHandler(msg: string, vm: Vue, trace: string): void;
ignoredElements: (string | RegExp)[];
keyCodes: { [key: string]: number | number[] };
async: boolean;
}

export interface VueConstructor<V extends Vue = Vue> {

0 comments on commit c944827

Please sign in to comment.