vuex 源码的网址:https://github.com/vuejs/vuex/blob/dev/src/store.js
在介绍dispatch之前,先介绍一个函数:subscribeAction。
首先通过官方文档https://vuex.vuejs.org/zh/api/#subscribeaction来看一下这个api的作用:
订阅 store 的 action。handler
会在每个 action 分发的时候调用并接收 action 描述和当前的 store 的 state 这两个参数:
store.subscribeAction((action, state) => {
console.log(action.type)
console.log(action.payload)
})
这样设置之后,每次分发一个action,都会自动执行这个函数。
从 3.1.0 起,subscribeAction
也可以指定订阅处理函数的被调用时机应该在一个 action 分发之前还是之后 (默认行为是之前):
store.subscribeAction({
before: (action, state) => {
console.log(`before action ${action.type}`)
},
after: (action, state) => {
console.log(`after action ${action.type}`)
}
})
现在先看看这个API的源码:
subscribeAction (fn) {
const subs = typeof fn === 'function' ? { before: fn } : fn
return genericSubscribe(subs, this._actionSubscribers)
}
function genericSubscribe (fn, subs) {
if (subs.indexOf(fn) < 0) {
subs.push(fn)
}
return () => {
const i = subs.indexOf(fn)
if (i > -1) {
subs.splice(i, 1)
}
}
}
代码很简单,总的来说,就是将我们配置的对象/函数放到_actionSubscribers数组中。
然后再来看看dispatch这个方法:
dispatch (_type, _payload) {
// check object-style dispatch
const {
type,
payload
} = unifyObjectStyle(_type, _payload)
const action = { type, payload }
const entry = this._actions[type]
if (!entry) {
if (process.env.NODE_ENV !== 'production') {
console.error(`[vuex] unknown action type: ${type}`)
}
return
}
try {
this._actionSubscribers
.filter(sub => sub.before)
.forEach(sub => sub.before(action, this.state))
} catch (e) {
if (process.env.NODE_ENV !== 'production') {
console.warn(`[vuex] error in before action subscribers: `)
console.error(e)
}
}
const result = entry.length > 1
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
return result.then(res => {
try {
this._actionSubscribers
.filter(sub => sub.after)
.forEach(sub => sub.after(action, this.state))
} catch (e) {
if (process.env.NODE_ENV !== 'production') {
console.warn(`[vuex] error in after action subscribers: `)
console.error(e)
}
}
return res
})
}
总体上来说,就是先把_actionSubscribers数组中的before的函数都执行完之后,在分发action对应的类型。执行完毕之后在执行_actionSubscribers数组after配置的方法。值得注意的是,分发action的时候采用了Promise。所以比较适合在action里面执行异步函数。