はじめに
こんにちは。Vuex最近微妙じゃね?って周りで騒がれて、「俺、Vuex使ってるけど、、やめたほうがいいならどうしたらいいんだろう・・・」って最近悩んでいる今日この頃。
Vueでaxiosを使って、連続でAPIをコールする際に、Promise.allやaxios.allを使ってまとめて投げて、まとめて受け取れるということを知ったときにはまった内容です。
axiosを使って、
1. 複数URL情報を格納した配列をまとめてAPI送信して、まとめて結果を受け取れる
2. まとめて投げているAPIで一つのURLのAPIコールが失敗しても処理を停止しない
3. Async/Awaitを使って同期的に処理する
を実現してくれる方法はないかと、
「どこかのAPIコールで失敗しても、処理を続けてうまくいったものとそうではないもの全部結果として受け取ってくれよ・・・」と
かなり錯綜して、見つけた方法を自分用メモとして残します。
内容
あるコンポーネントファイルから、dispatchでVuex内部にあるactionsの関数にアクセスして、そこからaxiosを使ってAPIを叩いています。
ざっくりとしたファイル構成は以下になります。(本当はもっと細かく分けています。ファイル名も適当です。)
.
┣ component.vue
┗ store
┣ modules
┃ ┗ api.js
┗ index.js
結論
axiosに情報を渡すまでの処理
export default {
methods: {
async getMultiInfo(bundledUrls) {
// 本来ここに複数のURLを格納した配列を作成します。
// 何なら、引数で渡してもいいと思います。
// const bundledUrls = [];
await this.$store.dispatch('api/getMultiInfo', {
url: bundledUrls
})
.then(response => {
this.infoCallingApi = this.$store.getters['api/getApiData'];
}, error => {
console.log("getMultiInfo:error: ", error);
})
},
},
}
axiosに情報を渡してくるものを受け取る側
・storeのルーティング
import Vue from 'vue'
import Vuex from 'vuex'
import api from './modules/api'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
api
}
})
export default store
・APIの受け渡しを管理している場所
import axios from 'axios'
const state = {
somethingdata: "",
}
const getters = {
getApiData(state) {
return state.somethingdata
}
}
const mutations = {
getApiData(state, payload) {
state.somethingdata = payload.data
}
}
const actions = {
async getMultiInfo(context, payload) {
const payload_tmp_data = {
data: "",
}
const postIds = payload.url;
const posts = postIds.map(
post => {
var a = axios
.get(post, { timeout: 60 * 1000 })
.then(res => res)
.catch(e => e)
return a
})
await Promise.all(posts).then(response => {
payload_tmp_data.data = response
}).catch(error => {
console.log(error)
}).finally(() => {
context.commit('getApiInfo', payload_tmp_data)
});
},
}
所感
「複数URL情報を格納した配列をまとめてAPI送信して、まとめて結果を受け取れる」ためにaxios.allやPromise.allを使えばいいことや
「Async/Awaitを使って同期的に処理する」を書くこと自体はすぐできたのですが、
「まとめて投げているAPIで一つのURLのAPIコールが失敗しても処理を停止しない」がPromise.allで全くできず、調べても、一つのAPIコールで失敗すると全部が失敗した判定になりますと書いてあってかなり苦戦しました。
結論の内容を使用すると、仮にどこかのAPIコールで失敗しても、その内容は無視してくれるようになります。
ちなみに、以下の記事を参考にしました。本当に有難いです。
参考:https://dev.to/jhalvorson/how-do-i-use-async-await-with-array-map-1h3f