Vuex源码解析(五) commit dispatch 实现

70 阅读1分钟

commit 实现

总述:

  • 解构对于的参数,确保能准确的拿到参数
  • 去mutations找对应的Fn,找到就保存下来,找不到就直接返回
  • 通过 _withCommit 方法能保证找到正确的mutations里面的Fn,需要遍历执行
  • 执行收集的 subscribe 的所有方法
/** 
* store.commit 方法
* 最终还是执行 mutation 方法
* @param {String} _type 方法名
* @param {Object} _payload 参数
* @param {Object} _options
*/
  commit (_type, _payload, _options) {
    // 解构 传进来的参数
    const {
      type,
      payload,
    } = unifyObjectStyle(_type, _payload, _options)
    // 保存 state payload
    const mutation = { type, payload }
    // 找到对应的 mutations => [addFn,addFn,...]
    const entry = this._mutations[type]
    // 没找到就直接返回
    if (!entry) return
    // 保证此处修改是符合规则的
    this._withCommit(() => {
       // 遍历 mutation 数组执行里面的 commit 方法
      entry.forEach(function commitIterator (handler) {
        handler(payload)
      })
    })
    // 执行收集的 subscribe 的所有方法
    this._subscribers
      .slice() 
      .forEach(sub => sub(mutation, this.state))

  }

dispatch 实现

  dispatch (_type, _payload) {
    const {
      type,
      payload
    } = unifyObjectStyle(_type, _payload)

    const action = { type, payload }
    const entry = this._actions[type]
    if (!entry) return

    try {
      this._actionSubscribers
        .slice() 
        .filter(sub => sub.before)
        .forEach(sub => sub.before(action, this.state))
    } catch (e) {

    }

    const result = entry.length > 1
      ? Promise.all(entry.map(handler => handler(payload)))
      : entry[0](payload)

    return new Promise((resolve, reject) => {
      result.then(res => {
        try {
          this._actionSubscribers
            .filter(sub => sub.after)
            .forEach(sub => sub.after(action, this.state))
        } catch (e) {

        }
        resolve(res)
      }, error => {
        try {
          this._actionSubscribers
            .filter(sub => sub.error)
            .forEach(sub => sub.error(action, this.state, error))
        } catch (e) {

        }
        reject(error)
      })
    })
  }