Axios/fatch发送请求后取消请求,React中使用AbortController

关于前端中断请求,其实很多业务场景中,我们都用到了这个功能,之前有一次面试,问道了这个,刚好手里有个需求,因为请求时间很长,为避免用户焦虑,于是加上一个暂停请求的功能。

正常情况下,我们使用ajax/axios/fatch来发动请求

关键代码直接看文末,照抄就对啦

1.原生AJAX的终止请求,可以用abort(),

XMLHttpRequest.abort()方法用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState属性变为4status属性变为0

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/page.php', true);
setTimeout(function () {
  if (xhr) {
    xhr.abort();
    xhr = null;
  }
}, 5000);

上面代码在发出5秒之后,终止一个 AJAX 请求。

这是官网的示例代码,因为开发过程中没有用到ajax,所以带过一下,AJAX -- JavaScript 标准参考教程(alpha)

2.axios中终止请求,AbortController

axios的0.22版本后,需要使用浏览器原生的AbortController来终止请求,当使用该方法终止请求时,如果对应请求已经被发送并且正在处理中,则会中止该请求;如果请求已经完成(即已经接收到完整的响应),则不会执行任何操作。

AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。

可以使用 AbortController.AbortController() 构造函数创建一个新的 AbortController。使用 AbortSignal 对象可以完成与 DOM 请求的通信。

AbortController.signal  

返回一个 AbortSignal 对象实例,它可以用来 with/abort 一个 Web(网络)请求。

AbortController.abort()

中止一个尚未完成的 Web(网络)请求。这能够中止 fetch 请求及任何响应体的消费和流,比如暂停视频的下载等

在下面的代码片段中,我们想通过 Fetch API 下载一段视频。

我们先使用 AbortController() 构造函数创建一个控制器,然后使用 AbortController.signal 属性获取其关联 AbortSignal 对象的引用。

当 fetch 请求初始化时,我们将 AbortSignal 作为一个选项传递进入请求的选项对象中(下面的 {signal})。这将 signal 和 controller 与 fetch 请求相关联,并且允许我们通过调用 AbortController.abort() 去中止它,如下面的第二个事件监听器。

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}`);
    });
}

在React中,终止axios的示例Demo,我是在函数组件中实现

首先在接口中,添加config

export const text2Img = (data,config) => {
    return Api.post('/tools/text2Img', data,config)
}
import React, { useState, useEffect } from 'react';
import { text2ImgFn } from './api'

export const App = () => {
    const [controller, setController] = useState(null)
    const getData = async () => {
        const abortController = new AbortController();
        setController(abortController);
        try {
            const res=await text2ImgFn(data,{signal:abortController.signal})
        } catch (err){
            console.log(err,'终止')
        }
    }
    const stopFn=()=>{
        controller.abort()
    }

    useEffect(() => {
        return () => {
            if (controller) {
                controller.abort();
            }
        };
    }, [])

    return (
        <div>
            <button onClick={getData}>发送</button>
            <button onClick={stopFn}>终止</button>
        </div>
    )


}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值