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

Vuex store not updated when called from promise resolution

我有一个绑定到 vuex 数据存储的数组,并通过 mapGetters 帮助程序公开为计算的 属性。这个数组叫做 items,我调用一个 REST API 在组件的 created() 挂钩中更新它。我为此 returns 执行的 vuex 操作是在解析之前访问 API 并调用增变器(更新 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 是空的。反应是否在 promise 解决后才开始?

简而言之

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

调用created时,执行:

this.$store.dispatch('fetchList')

立即

关注
console.log(this.items)

不用等待任何东西,然后,当this.$store.dispatch('fetchList') resolves时,.then.then(undefined)一样被调用...因为console.log(this.items) returns 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;
    }
);

我认为您的新 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>