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

时间:2017-10-10 15:24:22

标签: asynchronous promise vue.js store vuex

在我的一个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设置器中添加了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应该是最后一次记录,否则我无法正确处理数据。为什么它以随机顺序执行,为了解决它可以做些什么?

1 个答案:

答案 0 :(得分:0)

首先,我需要纠正自己,调度是一个动作,它是异步的,所以你要正确使用它们的promises。 (我以前用来绘制行动,所以我不太了解它们)

无论如何,承诺的重点是缓解回调地狱&#34;。所以,如果您的结构嵌套如下:

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

你首先打败了使用承诺的重点。

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

  • 动作
  • 动作
  • 动作
  • 动作
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中返回promise时,下一个then()将处理它,无论是使用此函数还是在函数之外 - 你最后的捕获将在承诺链的任何地方记录错误