【发布时间】:2021-06-05 19:48:58
【问题描述】:
上下文
我有两个商店模块:“会议”和“需求”。 在商店“Demands”中我有“getDemands”动作,在商店“Meetings”中我有“getMeetings”动作。在访问 Firestore 中的会议数据之前,我需要知道需求的 ID(例如:需求 [i].id),因此“getDemands”操作必须在“getMeetings”被调度之前运行并完成。
Vuex 文档dispatching-action 非常完整,但我仍然不知道如何将其放入我的代码中。这里还有一些关于该主题的其他很好回答的问题:
我想知道实现我想要完成的任务的最佳方式。从我的角度来看,这可以通过触发另一个动作或使用异步/等待来完成,但我在实现它时遇到了麻烦。
dashboard.vue
computed: {
demands() {
return this.$store.state.demands.demands;
},
meetings() {
return this.$store.state.meetings.meetings;
}
},
created() {
this.$store.dispatch("demands/getDemands");
//this.$store.dispatch("meetings/getMeetings"); Try A : Didn't work, seems like "getMeetings" must be called once "getDemands" is completed
},
VUEX 商店 模块 A – requirements.js
export default {
namespaced: true,
state: {
demands:[], //demands is an array of objects
},
actions: {
// Get demands from firestore UPDATED
async getDemands({ rootState, commit, dispatch }) {
const { uid } = rootState.auth.user
if (!uid) return Promise.reject('User is not logged in!')
const userRef = db.collection('profiles').doc(uid)
db.collection('demands')
.where('toUser', "==", userRef)
.get()
.then(async snapshot => {
const demands = await Promise.all(
snapshot.docs.map(doc =>
extractDataFromDemand({ id: doc.id, demand: doc.data() })
)
)
commit('setDemands', { resource: 'demands', demands })
console.log(demands) //SECOND LOG
})
await dispatch("meetings/getMeetings", null, { root: true }) //UPDATE
},
...
mutations: {
setDemands(state, { resource, demands }) {
state[resource] = demands
},
...
模块 B – meeting.js
export default {
namespaced: true,
state: {
meetings:[],
},
actions: {
// Get meeting from firestore UPDATED
getMeetings({ rootState, commit }) {
const { uid } = rootState.auth.user
if (!uid) return Promise.reject('User is not logged in!')
const userRef = db.collection('profiles').doc(uid)
const meetings = []
db.collection('demands')
.where('toUser', "==", userRef)
.get()
.then(async snapshot => {
await snapshot.forEach((document) => {
document.ref.collection("meetings").get()
.then(async snapshot => {
await snapshot.forEach((document) => {
console.log(document.id, " => ", document.data()) //LOG 3, 4
meetings.push(document.data())
})
})
})
})
console.log(meetings) // FIRST LOG
commit('setMeetings', { resource: 'meetings', meetings })
},
...
mutations: {
setMeetings(state, { resource, meetings }) {
state[resource] = meetings
},
...
【问题讨论】:
-
getDemands收到数据并提交后,应该是return dispatch("meetings/getMeetings")。这样,使用dispatch('demands/getDemands')它的.then()实际上将在getMeetings完成它正在做的任何事情之后发生。作为替代方案,您可以声明demands/getDemandsasync并在调度getMeetings之前使用await。这样返回demands将等待getMeetings。附注:您不应该return来自操作的数据。您应该将其提交给state,组件将得到更新,因为它们使用状态数据。 -
在
getMeetings中,for循环有几个问题:(1)它在一次迭代后返回。您可能想为所有demands运行正文,而不仅仅是第一个。如果正文是异步的,则需要使用Promise.all来累积meetings。 (2)条件表达式有赋值,但应该是比较。 -
@tao @tony19 感谢您的帮助,我已尝试实现整体并删除数据返回,但是我仍然无法弄清楚如何确保在运行之前终止
getDemandsgetMeetings。我更新了代码并添加了日志顺序。
标签: javascript vue.js google-cloud-firestore vuejs2 vuex