mirror of https://github.com/vuejs/vue.git
save and throw async stack trace in debug mode
This commit is contained in:
parent
da315f840b
commit
b9d8ad37ce
|
|
@ -73,15 +73,12 @@ exports.$delete = function (key) {
|
|||
|
||||
exports.$watch = function (exp, cb, options) {
|
||||
var vm = this
|
||||
var wrappedCb = function (val, oldVal) {
|
||||
cb.call(vm, val, oldVal)
|
||||
}
|
||||
var watcher = new Watcher(vm, exp, wrappedCb, {
|
||||
var watcher = new Watcher(vm, exp, cb, {
|
||||
deep: options && options.deep,
|
||||
user: !options || options.user !== false
|
||||
})
|
||||
if (options && options.immediate) {
|
||||
wrappedCb(watcher.value)
|
||||
cb.call(vm, watcher.value)
|
||||
}
|
||||
return function unwatchFn () {
|
||||
watcher.teardown()
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ var uid = 0
|
|||
*/
|
||||
|
||||
function Watcher (vm, expOrFn, cb, options) {
|
||||
// mix in options
|
||||
if (options) {
|
||||
_.extend(this, options)
|
||||
}
|
||||
var isFn = typeof expOrFn === 'function'
|
||||
this.vm = vm
|
||||
vm._watchers.push(this)
|
||||
|
|
@ -32,23 +36,16 @@ function Watcher (vm, expOrFn, cb, options) {
|
|||
this.cb = cb
|
||||
this.id = ++uid // uid for batching
|
||||
this.active = true
|
||||
options = options || {}
|
||||
this.deep = !!options.deep
|
||||
this.user = !!options.user
|
||||
this.twoWay = !!options.twoWay
|
||||
this.sync = !!options.sync
|
||||
this.lazy = !!options.lazy
|
||||
this.dirty = this.lazy
|
||||
this.filters = options.filters
|
||||
this.preProcess = options.preProcess
|
||||
this.dirty = this.lazy // for lazy watchers
|
||||
this.deps = []
|
||||
this.newDeps = null
|
||||
this.prevError = null // for async error stacks
|
||||
// parse expression for getter/setter
|
||||
if (isFn) {
|
||||
this.getter = expOrFn
|
||||
this.setter = undefined
|
||||
} else {
|
||||
var res = expParser.parse(expOrFn, options.twoWay)
|
||||
var res = expParser.parse(expOrFn, this.twoWay)
|
||||
this.getter = res.get
|
||||
this.setter = res.set
|
||||
}
|
||||
|
|
@ -196,6 +193,11 @@ p.update = function (shallow) {
|
|||
: false
|
||||
: !!shallow
|
||||
this.queued = true
|
||||
// record before-push error stack in debug mode
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' && config.debug) {
|
||||
this.prevError = new Error('[vue] async stack trace')
|
||||
}
|
||||
batcher.push(this)
|
||||
}
|
||||
}
|
||||
|
|
@ -216,9 +218,28 @@ p.run = function () {
|
|||
// non-shallow update (caused by a vm digest).
|
||||
((_.isArray(value) || this.deep) && !this.shallow)
|
||||
) {
|
||||
// set new value
|
||||
var oldValue = this.value
|
||||
this.value = value
|
||||
this.cb(value, oldValue)
|
||||
// in debug + async mode, when a watcher callbacks
|
||||
// throws, we also throw the saved before-push error
|
||||
// so the full cross-tick stack trace is available.
|
||||
var prevError = this.prevError
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== 'production' &&
|
||||
config.debug && prevError) {
|
||||
this.prevError = null
|
||||
try {
|
||||
this.cb.call(this.vm, value, oldValue)
|
||||
} catch (e) {
|
||||
_.nextTick(function () {
|
||||
throw prevError
|
||||
}, 0)
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
this.cb.call(this.vm, value, oldValue)
|
||||
}
|
||||
}
|
||||
this.queued = this.shallow = false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ describe('Data API', function () {
|
|||
var unwatch = vm.$watch('a + b.c', spy, {
|
||||
immediate: true
|
||||
})
|
||||
expect(spy).toHaveBeenCalledWith(3, undefined)
|
||||
expect(spy).toHaveBeenCalledWith(3)
|
||||
vm.a = 2
|
||||
nextTick(function () {
|
||||
expect(spy).toHaveBeenCalledWith(4, 3)
|
||||
|
|
@ -112,7 +112,7 @@ describe('Data API', function () {
|
|||
var unwatch = vm.$watch(function () {
|
||||
return this.a + this.b.c
|
||||
}, spy, { immediate: true })
|
||||
expect(spy).toHaveBeenCalledWith(3, undefined)
|
||||
expect(spy).toHaveBeenCalledWith(3)
|
||||
vm.a = 2
|
||||
nextTick(function () {
|
||||
expect(spy).toHaveBeenCalledWith(4, 3)
|
||||
|
|
|
|||
Loading…
Reference in New Issue