如何在Vuex动作完成之前阻止Vue生命周期继续进行?

时间:2019-07-06 19:56:40

标签: vue.js promise axios vuex

在我的应用程序中,我想在其余应用程序启动之前初始化3个Vuex模块。但是,无论我如何尝试,我执行初始化的Vue实例生命周期挂钩中的代码都会在3个模块完成初始化之前继续执行。

我在执行初始化的Vuex操作中的代码周围添加了一个承诺,以便我可以(a)等待调用生命周期挂钩中的代码,但这是行不通的。

我已经看过使用Axios的Vuex示例代码,我必须使我的代码与此相似,但没有成功。

我尝试使用“ Promise.all(...)”在“ beforeCreate”生命周期挂钩中进行init调用,但这仍然无法解决。

我的主要Vue实例的代码如下:

new Vue({
  router,
  store,
  async beforeCreate() {
    await this.$store.dispatch('init')
  },
  render: h => h(App)
}).$mount('#app')

Vuex存储由3个模块组成,所有模块均具有“ init”操作。这三个模块中的操作代码都相同。如果下面的代码中有“ XXX”,则每个模块的调用会稍有不同;

  init: ({commit, dispatch}) => {
    return new Promise((resolve, reject) => {
      console.log('Start of init of XXX');
      Axios.get(`api/xxx`).then(response => {
        return response.data;
      }, error => {
        console.log('An error occured: ', error);
        reject(error);
      }).then(data => {
        const result = [];
        for (let key in data) {
          result.push(data[key]);
        }

        console.log('The API call resulted in ' + result.length + ' lines of code');

        resolve(result);
        commit('ADD_XXX', result);
      })
    })
  }

我期望的是“ beforeCreate”代码继续进行下去,直到3个init动作调用已完全完成(即,直到所有诺言都已兑现)为止。

我看到的是动作已开始(我在控制台中看到“开始初始化...”日志)。但是然后我看到一个应用程序组件之一的mounted()函数中的代码开始执行,它不应该执行,因为如果存储未完全初始化,它将无法正常工作。

1 个答案:

答案 0 :(得分:1)

您不能通过使其beforeCreate暂停async。当您按下await时,它似乎在内部被“暂停”,但从外部角度来看,它只是返回一个承诺。 Vue不会注意返回值,因此Promise将被忽略,并且生命周期将持续不断。您可以做的是在data中添加一些状态,并对其进行处理以达到所需的效果:

new Vue({
  router,
  store,
  data () {
    return {
      ready: false
    }
  },
  async beforeCreate() {
    await this.$store.dispatch('init')
    this.ready = true
  },
  render (h) {
     if (this.ready) {
       return h(App)
     }
  }
}).$mount('#app')

顺便说一句,您不需要在init中创建新的Promise,只需返回axios创建的链式Promise。

更新

这是另一种方法,只是阻止呼叫mount

new Vue({
  router,
  store,
  async beforeCreate() {
    await this.$store.dispatch('init')
    this.$mount('#app')
  },
  render: h => h(App)
})