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()
将处理它,无论它是在这个函数内还是在它之外
- 你最后的捕获将在承诺链中的任何地方记录错误
在我的一个 vuex 模块中,我使用 then()
:
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()
将处理它,无论它是在这个函数内还是在它之外
- 你最后的捕获将在承诺链中的任何地方记录错误