リクエスト送信プロセス中に、サーバーがリクエストを返す前に手動でリクエストをキャンセルできます。
ネイティブ ajax
リクエストは、リクエスト オブジェクトのメソッドを介してキャンセルできますabort()
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
// 获取元素;
const btns = document.getElementsByTagName('button');
let xhr = null
// 发送请求
btns[0].onclick =function (){
xhr = new XMLHttpRequest();
xhr.open('GET','http://127.0.0.1:8000/delay')
xhr.send()
}
// abort取消请求
btns[1].onclick = function (){
xhr.abort();
}
</script>
</body>
</html>
アクシオス
道:
1. AbortController : v0.22.0以降、axiosはfetch APIメソッドをサポートしますAbortController
.—リクエストのキャンセル.このメソッドでは、axiosのバージョンに注意する必要があり、v0.22.0未満では失敗します.
2. cancelToken: この API は v0.22.0 から廃止されました不应在新项目中使用
。ただし、私のaxiosの現在のバージョンv1.2.0は引き続き使用できますcancelToken
fetch と ajax の違いを知りたい場合は、この記事を読むことができます: https://zhuanlan.zhihu.com/p/401232894
AbortController
インターフェイスは、必要に応じて 1 つまたは複数の Web リクエストを中止できるコントローラー オブジェクトを表します。
MDN の公式ドキュメントの例を見てください:
let controller;
const url = 'video.mp4';
const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');
downloadBtn.addEventListener('click', fetchVideo);
abortBtn.addEventListener('click', () => {
if (controller) {
controller.abort();
console.log('中止下载');
}
});
function fetchVideo() {
controller = new AbortController();
const signal = controller.signal;
fetch(url, {
signal })
.then((response) => {
console.log('下载完成', response);
})
.catch((err) => {
console.error(`下载错误:${
err.message}`);
});
}
アクシオスで使用
this.abortController = new AbortController();
const res = await http({
url: 'http://0.0.0.0:8088',
method: 'get',
signal: this.abortController.signal, // 带上参数
params: {
}
}).catch((err) => {
this.isRequesting3 = false;
console.log(err);
})
cancel メソッドで直接呼び出される
this.abortController.abort();
複数の繰り返しリクエストをキャンセルする
httpRequest.js
import axios from 'axios'
import store from '@/store'
import {
message } from 'ant-design-vue'
const CancelToken = axios.CancelToken
let pedding = {
}
const service = axios.create({
baseURL: '/',
timeout: 60000,
})
service.interceptors.request.use(config => {
config.headers['token'] = store.state.user.token
// 在参数中加个isCancelToken,用来判断该接口是否需要做多次请求取消上一个请求的操作
if (config.isCancelToken) {
// 第一种 AbortController
const controller = new AbortController();
config['signal'] = controller.signal
pedding[config.url + '&' + config.method] && pedding[config.url + '&' + config.method].abort()
pedding[config.url + '&' + config.method] = controller
// 第二种 CancelToken.source
const source = CancelToken.source()
config['cancelToken'] = source.token
pedding[config.url + '&' + config.method] && pedding[config.url + '&' + config.method].cancel()
pedding[config.url + '&' + config.method] = source
// 第三种 CancelToken
pedding[config.url + '&' + config.method] && pedding[config.url + '&' + config.method]()
config['cancelToken'] = new CancelToken((c) => {
pedding[config.url + '&' + config.method] = c
})
}
return config
}, error => {
return Promise.reject(error)
})
service.interceptors.response.use(response => {
// 这里删除key
pedding[response.config.url + '&' + response.config.method] && delete pedding[response.config.url + '&' + response.config.method]
if (response.data.code == 200) {
return response.data
} else {
message.error(response.data.msg)
return Promise.reject(response.data)
}
}, error => {
return Promise.reject(error)
})
export default service
上記の 3 つの方法のいずれかを選択できます。
使用
home.vue
<template>
<div>
<a-button>home</a-button>
<router-link to="/about">跳转about</router-link>
<a-input placeholder=""></a-input>
<a-checkbox></a-checkbox>
</div>
</template>
<script>
import {
login } from '@/axios/api/home'
export default {
setup() {
login({
timeRange: 'ONE_DAY'}).then(res => {
console.log('第一次调用-success')
}).catch((err) => {
console.log('第一次调用-err')
})
setTimeout(() => {
login({
timeRange: 'ONE_DAY', num: 1}).then(res => {
console.log('第二次调用-success')
}).catch((err) => {
console.log('第二次调用-err')
})
}, 200)
}
}
</script>
<style lang="scss" scoped>
</style>
home.js
import request from '@/axios'
export const login = (data) => {
return request({
url: '/dc/pc/heatMap',
method: 'get',
params: data,
isCancelToken: true
})
}
複数のリクエストが順番に返されるようにする
- promise.all を使用する
- リクエストインターフェースにはインデックス識別子があり、バックエンドとの合意に従って返されるデータに含まれ、結果を取得した後にソートされます