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.
  • Loading branch information
eddyerburgh authored and yyx990803 committed Aug 16, 2018
1 parent 833175e commit c944827
Show file tree
Hide file tree
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
Expand Up @@ -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>;
};
Expand Down Expand Up @@ -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
*/
Expand Down
7 changes: 7 additions & 0 deletions src/core/observer/dep.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

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

let uid = 0

Expand Down Expand Up @@ -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()
}
Expand Down
5 changes: 5 additions & 0 deletions src/core/observer/scheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
67 changes: 67 additions & 0 deletions test/unit/features/global-api/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -73,6 +73,7 @@ class Test extends Vue {
};
config.keyCodes = { esc: 27 };
config.ignoredElements = ['foo', /^ion-/];
config.async = false
}

static testMethods() {
Expand Down
1 change: 1 addition & 0 deletions types/vue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down

0 comments on commit c944827

Please sign in to comment.