Durante el proceso de envío de la solicitud, podemos cancelar manualmente la solicitud antes de que el servidor la devuelva.
ajax nativo
La solicitud se puede cancelar a través de los métodos del objeto de solicitud 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>
axios
Forma:
1. AbortController : a partir de la versión 0.22.0, axios admite el método de obtención de la APIAbortController
: cancelación de solicitud. En este método, debe prestar atención a la versión de axios y fallará por debajo de la versión 0.22.0.
2. cancelToken: esta API está obsoleta desde la v0.22.0, 不应在新项目中使用
. Sin embargo, todavía se puede usar mi versión actual de axios v1.2.0cancelToken
Si desea conocer la diferencia entre fetch y ajax, puede leer este artículo: https://zhuanlan.zhihu.com/p/401232894
AbortController
La interfaz representa un objeto controlador que le permite anular una o más solicitudes web según sea necesario.
Eche un vistazo al ejemplo de documentación oficial en 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}`);
});
}
uso en axios
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);
})
Llamado directamente en el método de cancelación
this.abortController.abort();
Cancelar varias solicitudes repetidas
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
Puede elegir uno de los tres métodos anteriores.
usa
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>
casa.js
import request from '@/axios'
export const login = (data) => {
return request({
url: '/dc/pc/heatMap',
method: 'get',
params: data,
isCancelToken: true
})
}
Asegúrese de que se devuelvan varias solicitudes en orden
- usar promesa.todo
- Hay un identificador de índice en la interfaz de solicitud, y se incluye en los datos devueltos según lo acordado con el backend, y se ordena después de obtener los resultados.