AbortController
AbortController() 构造函数创建了一个新的 AbortController 实例。MDN官网给出了一个利用AbortController取消下载视频的例子。
核心逻辑是:利用AbortController接口的只读属性signal标记fetch哀求;然后在需要取消哀求的时候,调用AbortController接口的abort()方法立即取消哀求,并抛出一个错误AbortError。
- const controller = new AbortController();
- const signal = controller.signal;
- const url = "video.mp4";
- const downloadBtn = document.querySelector(".download");
- const abortBtn = document.querySelector(".abort");
- downloadBtn.addEventListener("click", fetchVideo);
- abortBtn.addEventListener("click", () => {
- controller.abort();
- console.log("Download aborted");
- });
- function fetchVideo() {
- fetch(url, { signal })
- .then((response) => {
- console.log("Download complete", response);
- })
- .catch((err) => {
- console.error(`Download error: ${err.message}`);
- });
- }
复制代码 只读属性signal
AbortController接口的只读属性 signal 返回一个 AbortSignal 实例对象,该对象可以根据需要处理 DOM 哀求通讯,既可以创建通讯,也可以终止通讯。
方法:abort()
AbortController接口的 abort() 方法会在 DOM 哀求完成之前中止它。它可以或许中止 fetch 哀求、各种响应主体或者流的消耗。
取消Axios哀求
既然 AbortController接口的 abort() 方法可以终止fetch哀求、各种响应主体或者流的消耗,那么我们思量将其和axios联合,来取消axios的哀求。
查看axios官网,也给出了干系先容:
为了便于在项目中利用,我们在对其举行一个简朴的封装,示比方下:
- //axios配置
- function createRequest() {
- const request = axios.create({
- baseURL: "https://geo.datav.aliyun.com",
- headers: {
- "Content-Type": "application/json;charset=utf-8",
- }
- })
- const cachePool = new Map()
- const encode = (baseURL, method, url, params) => {
- const str = `${baseURL}_${url}_${method}_${JSON.stringify(params || {})}`;
- const encoder = new TextEncoder();
- //接受一个字符串作为输入,返回一个包含 UTF-8 编码的文本的 Uint8Array
- const bytes = encoder.encode(str)
- //使用Base64编码算法进行编码:将一个二进制字符串(例如,将字符串中的每一个字节都视为一个二进制数据字节)编码为 Base64 编码的 ASCII 字符串
- const encoded = btoa(String.fromCharCode(...bytes))
- return encoded
- }
- /**
- * 对Axios请求实例的config进行编码
- * */
- const configEncode = (config) => {
- //获取基本信息
- const baseURL = config.baseURL,
- method = config.method,
- url = config.url,
- params = config?.params || config?.data || {};
- //返回编码结果
- return encode(baseURL, method, url, params);
- }
- //请求拦截器
- request.interceptors.request.use(
- (config) => {
- // 在发送请求之前做些什么
- console.log(config)
- const controller = new AbortController()
- config.signal = controller.signal
- //根据config配置信息进行编码
- const encodeKey = configEncode(config)
- console.log("encodeKey:", encodeKey)
- //判断请求是否存在
- if (cachePool.get(encodeKey)) {
- controller.abort()
- console.log('cachePool--cancel:', cachePool)
- } else {
- cachePool.set(encodeKey, { abort: controller })
- console.log('cachePool--set:', cachePool)
- }
- return config;
- },
- (error) => {
- // 对请求错误做些什么
- console.log(error);
- return Promise.reject(error);
- }
- );
- //响应拦截器
- // 添加响应拦截器
- request.interceptors.response.use(function (response) {
- // 2xx 范围内的状态码都会触发该函数。
- // 对响应数据做点什么
- const encodeKey = configEncode(response.config)
- console.log('response---:', response, encodeKey)
- //缓存对象
- const cacheItem = cachePool.get(encodeKey)
- if (cacheItem) {
- console.log("res-success:删除缓存对象")
- cachePool.delete(encodeKey)
- }
- return response;
- }, function (error) {
- // 超出 2xx 范围的状态码都会触发该函数。
- // 对响应错误做点什么
- console.log('axios-error:', error)
- if (error.code === "ERR_CANCELED") {
- //被取消的axios请求
- console.warn(`被取消的重复请求~`)
- } else {
- //其它错误
- return Promise.reject(error);
- }
- });
- //返回
- return request
- }
复制代码 接下来做个简朴的测试,
- const request = createRequest()
- const getData = () => {
- return request.get("/areas_v3/bound/420800_full.json", {
- params: {
- a: 1
- }
- })
- }
- getData().then(result => {
- console.log(result)
- })
- getData().then(result => {
- console.log(result)
- })
- getData().then(result => {
- console.log(result)
- })
复制代码 查看实行效果:一连发送了3次哀求,后两个被取消掉,终极只有一个哀求正常返回了哀求效果。
别的取消Axios哀求的方式
参考:Vue:Axios前端拦截器_vue axios拦截器-CSDN博客
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |