Vuex - 使用 then() 时,来自不同模块的数据以随机顺序返回

Vuex - data from different modules are returned in random order when using then()

在我的一个 vuex 模块中,我使用 then():

使用 3 个不同的 API 请求逐步加载数据 3 次
 actions: {
    loadRoamingHistory: function loadRoamingHistory(context, roamingFilter): Promise<Array<RoamingHistoryEvent>> {
      return new Promise((resolve) => {

        store.dispatch('network/loadNetworks').then(() => { 
          store.dispatch('country/loadCountries').then(() => {

            providerApi.loadRoamingHistory(roamingFilter).then(data => { 

                // read already loaded networks and countries from store
                let networks = context.rootState.network.networks;
                let countries = context.rootState.country.countries;

                // .. some data processing using informations from 
                // networks and countries request, that are not allways available at this point..

                console.log('data processing');

                commitSetRoamingHistoryEvents(context, data.roamingHistoryEvent);
                resolve();

            }).catch(err => console.log(err));
          });
        });
      });
    }  
  }

我还向网络和国家 vuex setter 添加了 console.log() 命令,以便查看首先执行的内容:

  mutations: {
    setNetworks: function setNetworks(state: NetworkState, networks: Array<Network>) {
      console.log('networks loaded');
      state.networks = networks;
    },

我希望这 3 个请求被一个一个地执行,但是日志消息显示有时它以不同的顺序执行,例如日志消息是这样的:

networks loaded
countries loaded
networks loaded
data processing
countries loaded

注意data processing应该是最后一条日志,否则无法正确处理数据。为什么它以随机顺序执行,可以做些什么来修复它?

首先我要纠正一下,dispatch是一个action,是异步的,所以你用promises是对的。 (习惯了映射动作,所以看的不多)

无论如何,承诺的目的是缓解 "callback hell"。所以如果你的结构是这样嵌套的:

  • 动作
    • 动作
      • 动作
        • 动作

你一开始就违背了使用 promise 的意义。

相反,重点是以可读的方式将它们链接在一起

  • 动作
  • 动作
  • 动作
  • 动作
actions: {
  loadRoamingHistory: function loadRoamingHistory(context, roamingFilter): Promise<Array<RoamingHistoryEvent>> {
    return store.dispatch('network/loadNetworks')
      .then(() => {
        return store.dispatch('country/loadCountries')
      })
      .then(() => {
        return providerApi.loadRoamingHistory(roamingFilter)
      })
      .then(data => { 
        // read already loaded networks and countries from store
        let networks = context.rootState.network.networks;
        let countries = context.rootState.country.countries;

        // .. some data processing using informations from 
        // networks and countries request, that are not allways available at this point..

        console.log('data processing');

        return commitSetRoamingHistoryEvents(context, data.roamingHistoryEvent);
      })
      .catch(err => console.log(err));
  }  
}

请注意... - 初始承诺未定义。因为分派是异步的,它已经创建了一个承诺,我们只需添加额外的调用即可。 - 当在 promise 中返回一个 promise 时,下一个 then() 将处理它,无论它是在这个函数内还是在它之外 - 你最后的捕获将在承诺链中的任何地方记录错误