やりたいこと
VueRouter
でroute変更時に、前のページで投げられていたリクエストを一括でキャンセルしたい。
これが出来ると、遷移前のページで大量にリクエストが投げられていた場合、遷移後のページのcreated
で実行するリクエストがすぐに実行出来るようになる。
サンプルコード
リクエストをキャンするするためのトークンなどを作る
リクエストをキャンするするためには、axios
でリクエストを投げる時にキャンセルトークンを設定する必要があるので、それを生成するクラスを作ってあげる。
リクエストキャンセル時には、以降のリクエストでは新しいキャンセルトークンが使えるようにしています。*1
import axios, { CancelTokenSource } from 'axios' class RequestCanceler { private source: CancelTokenSource = axios.CancelToken.source() cancel() { this.source.cancel() this.source = axios.CancelToken.source() } token() { return this.source.token } } const requestCanceler = new RequestCanceler() export { requestCanceler }
axiosでリクエストを投げる
axios
でリクエストを投げるときには、config
にcancelToken
を設定してあげます。
キャンセルが行われると例外が上がるので、axios.isCancel
を使ってキャンセルによる失敗なのかそれ以外なのかを判定してあげる必要があります。
import { requestCanceler } from './api' import axios from 'axios' axios.get(`http://localhost:8080/test`, {cancelToken: requestCanceler.token()}).then(res => { console.log(res.data) }).catch(reason => { if (axios.isCancel(reason)) { console.log('cancel!!!!') } else { console.log('cancelじゃないよ') } })
route変更時にリクエストを一括キャンセルする
VueRouter
のbeforeEach
でキャンセル処理を呼び出してリクエストを一括キャンセルしてあげます。
router.beforeEach((to, from, next) => { console.log('beforeEach') requestCanceler.cancel() next() })
動かしてみた結果
VueRouter
のbeforeEach
のログが出力された後に大量のcancel!!!が出力されているので、
キャンセル処理が動いてエラー処理でキャンセル処理の分岐に入っていることがわかりますね。