从promise解析调用时,Vuex存储未更新

时间:2017-11-06 10:43:52

标签: javascript vue.js promise vuex

我有一个绑定到vuex数据存储的数组,并通过mapGetters帮助器作为计算属性公开。此数组称为items,我调用REST API以在组件的created()挂钩中更新它。我为此提供的vuex操作返回一个promise,在该promise中,访问API并在解析之前调用mutator(更新items数组)。我对promises的理解告诉我,我的then调用应该在异步操作完成后安全地发生,但是如果我尝试从promise解析中访问items,它是空的尽管数组肯定是由API调用。为什么这不是我的期望?

代码已全部结束,但这里是相关部分

组件:

  computed: {
    ...mapGetters({
      items: 'allHistoryItems'
    }),
// ...
  created () {
    this.$store.dispatch('fetchList').then(console.log(this.items))
  }

动作:

  fetchList: ({ commit }) => {
    return new Promise((resolve, reject) => {
      fetchList().then(response => {
        commit(types.FETCH_LIST, response.data)
        resolve(response)
      })
    })
  }

我可以从组件访问API响应,但如上所述,items为空。在承诺结算之前,反应性是否会起作用?

2 个答案:

答案 0 :(得分:2)

简而言之

created () {
    this.$store.dispatch('fetchList').then(console.log(this.items))
}

调用created时,执行:

this.$store.dispatch('fetchList')

后立即
console.log(this.items)

不等待任何事情,然后,当this.$store.dispatch('fetchList')结算时,.then被调用为.then(undefined) ...因为console.log(this.items)返回undefined

将此更改为

created () {
    this.$store.dispatch('fetchList').then(() => console.log(this.items));
}

作为奖励 - 删除promise构造函数反模式:

fetchList: ({ commit }) => fetchList() 
    .then(response => {
        commit(types.FETCH_LIST, response.data);
        return response;
    }
);

答案 1 :(得分:0)

我认为你的新Promise构建简直就是多余的。检查这个简单的例子,如果它正在做你想要的:



var store = new Vuex.Store({
  state: {
    hero: []
  },
  mutations: {
    updateHero (state, payload) {

      state.hero = payload
    }
  },
  actions: {
    async loadHero ({commit}, payload) {
      var response = await fetch('https://swapi.co/api/people/1/')
      commit('updateHero', await response.json())
    }
  }
})

new Vue ({
  el: '#app',
  store,
  computed: {
    hero () {
      return this.$store.state.hero
    }
  },
  methods: Vuex.mapActions(['loadHero'])
})

[v-cloak] {
  display: none;
}

<div id="app">
  Hero name is: <span v-cloak>{{ hero.name }}</span><br>
  <button @click="loadHero">Load hero personal data</button>
</div>

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
&#13;
&#13;
&#13;