VueJS 调度函数的执行顺序导致问题

Posted

技术标签:

【中文标题】VueJS 调度函数的执行顺序导致问题【英文标题】:Order of Execution for VueJS dispatch function is causing an issue 【发布时间】:2022-01-05 00:11:34 【问题描述】:

我正在尝试在页面上显示公告列表(从 API 检索)。我正在使用 Vuex 商店,我有一个名为 announcements 的状态。我还希望每次用户刷新/进入页面时更新此列表。所以我使用了生命周期钩子,尤其是mounted()。 我有一个以俱乐部 ID 作为参数的调度函数。问题是我尝试访问 Vue 组件中的公告数组,它比 Vuex 商店中的版本落后了一个“步骤”。

以下是在Vue组件ClubDetails.vue中

  name: "ClubDetails",
  data()
    console.log("inside data")
    return 
      club_id: this.$route.params.clubID,
      announcements: this.$store.state.ClubDetails.announcements
    
  ,
  mounted() 
      this.$store.dispatch('ClubDetails/getAnnouncements', this.club_id)
      console.log("After dispatch function")
  ,

这是我的商店ClubDetails.js

    namespaced: true,
    state: 
        announcements: [],
    ,
    mutations: 
        setAnnouncements(state, newArr) 
            state.announcements = newArr
            console.log("Inside Mutation")
        ,
    ,
    actions: 
        async getAnnouncements( commit, state , club) 
            const params = new URLSearchParams([
                ['clubId', club]
            ]);
            await axios.get("http://127.0.0.1:8000/api/announcements",  params ).then(res => 
                console.log("inside dispatch function")
                commit('setAnnouncements', res.data)

            ).catch(err => 
                console.log(err)
            )
        ,
    ,
    getters: 
        getAllAnnouncements(state) 
            return state.announcements;
        
    ,
; 

在打印语句之后,执行顺序不是我所期望的

我希望顺序是这样的:内部数据 -> 内部调度 -> 内部突变 -> 调度之后。

另一个问题是,当我刷新页面时,我希望再次调用mounted() 并且数组将被更新并再次显示,但是刷新时数组的所有内容都消失了

【问题讨论】:

【参考方案1】:

这是因为this.$store.dispatch('ClubDetails/getAnnouncements', this.club_id) 正在对服务器做出响应,并且是异步的,并且从服务器获取通知需要时间。而 console.log("After dispatch function") 在从服务器收到响应之前被执行。

这就是为什么你首先看到调度函数之后,然后调度函数内部

尝试像这样在调度之前放置等待。

  async mounted() 
      await this.$store.dispatch('ClubDetails/getAnnouncements', this.club_id)
      console.log("After dispatch function")
  ,

你应该返回 axios.get 方法,因为它是一个 Promise 并且不需要使用 await 和 then 一起。您也可以从 getAnnouncements 中删除异步,因为您不再使用 await。

 getAnnouncements( commit, state , club) 
            const params = new URLSearchParams([
                ['clubId', club]
            ]);
            return axios.get("http://127.0.0.1:8000/api/announcements",  params ).then(res => 
                console.log("inside dispatch function")
                commit('setAnnouncements', res.data)

            ).catch(err => 
                console.log(err)
            )
        ,

【讨论】:

以上是关于VueJS 调度函数的执行顺序导致问题的主要内容,如果未能解决你的问题,请参考以下文章

是啥让线程的执行顺序不可预测?

golang 控制goroutine调度顺序

golang 控制goroutine调度顺序

关于父子进程的执行顺序和执行过程

多线程线程通信调度等待集 wait() notify()

Java--线程的先后执行顺序控制