从承诺解决方案调用时,Vuex 商店未更新
Posted
技术标签:
【中文标题】从承诺解决方案调用时,Vuex 商店未更新【英文标题】:Vuex store not updated when called from promise resolution 【发布时间】:2018-04-18 12:07:14 【问题描述】:我有一个绑定到 vuex 数据存储并通过 mapGetters
帮助器作为计算属性公开的数组。这个数组叫做items
,我在组件的created()
钩子中调用了一个REST API来更新它。我为此执行的 vuex 操作返回一个承诺,在该承诺中访问 API 并在解析之前调用 mutator(更新 items
数组)。我对 Promise 的理解告诉我,我的 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 解决后才开始反应?
【问题讨论】:
Avoid the promise constructor anti-pattern - 话虽如此,“动作”如何改变项目?我看不到连接 ahhh.then(console.log(this.items))
... 应该是 .then(() => console.log(this.items))
... .then 需要一个函数作为参数,而不是调用 console.log 的结果(顺便说一下未定义)跨度>
我会检查这篇文章。 Items 被映射到一个 getter,该 getter 操作并返回 API 获取的列表。
忽略我的第一条评论,你犯的错误在我的第二条评论中
想想它就是这么基本的东西。我稍后会对其进行测试,但将其变成答案,我会接受它。
【参考方案1】:
总之
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));
作为奖励 - 删除承诺构造函数反模式:
fetchList: ( commit ) => fetchList()
.then(response =>
commit(types.FETCH_LIST, response.data);
return response;
);
【讨论】:
【参考方案2】:我认为您的新 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>
【讨论】:
以上是关于从承诺解决方案调用时,Vuex 商店未更新的主要内容,如果未能解决你的问题,请参考以下文章