axios 请求取消及其实现过程

一、axios 请求取消
  1. axios 请求取消,代码如下所示:
<!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>axios 请求取消</title>
  <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  <script src="./node_modules/axios/dist/mine-axios.js"></script>
</head>
<body>
  <div class="container">
    <h2 class="page-header">axios取消请求</h2>
    <button class="btn btn-primary">发送请求</button>
    <button class="btn btn-warning">取消请求</button>
  </div>
  <script>
    // 获取按钮 
    const btns = document.querySelectorAll('button');
    // 声明全局变量
    let cancel = null;
    btns[0].onclick = function () {
      // 检测上一次的请求是否已经完成
      if (cancel !== null) {
        // 取消上一次的请求
        cancel();
      }

      // 创建 cancelToken 的值
      let cancelToken = new axios.CancelToken(
        function (c) {
          // 3. 将 c 的值赋值给 cancel
          cancel = c;
        });
      
      axios({
        method: 'GET',
        url: 'http://localhost:3000/posts',
        // 添加配置对象的属性
        cancelToken: cancelToken
      }).then(response => {
        console.log(response);
        // 将 cancel 的值初始化
        cancel = null;
      });
    }

    // 绑定第二个事件取消请求
    btns[1].onclick = function () {
      cancel();
    }
  </script>
</body>
</html>
二、axios 请求取消的实现过程
  1. axios 请求取消的实现过程,代码如下所示:
<!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>axios 请求取消的实现</title>
  <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  <!-- <script src="./node_modules/axios/dist/mine-axios.js"></script> -->
</head>
<body>
  <div class="container">
    <h2 class="page-header">axios取消请求</h2>
    <button class="btn btn-primary">发送请求</button>
    <button class="btn btn-warning">取消请求</button>
  </div>
  <script>
    // 构造函数
    function Axios (config) {
      this.config = config;
    }

    // 原型 request 方法
    Axios.prototype.request = function (config) {
      return dispatchRequest(config);
    }

    // dispatchRequest 函数 
    function dispatchRequest (config) {
      return xhrAdapter(config);
    }

    // xhrAdapter 函数
    function xhrAdapter (config) {
      // 发送 AJAX 请求
      return new Promise((resolve, reject) => {
        // 实例化对象
        const xhr = new XMLHttpRequest();
        // 初始化
        xhr.open(config.method, config.url);
        // 发送
        xhr.send();
        // 处理结果
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            // 判断结果
            if (xhr.status >= 200 && xhr.status < 300) {
              // 设置成功的状态
              resolve({
                status: xhr.status,
                statusText: xhr.statusText
              });
            } else {
              reject(new Error('请求失败'));
            }
          }
        }

        // 关于取消请求的处理
        if (config.cancelToken) {
          // 对 cancelToken 对象身上的 promise 对象指定成功的回调
          config.cancelToken.promise.then(value => {
            xhr.abort();
            // 将整体结果设置为失败
            reject(new Error('请求已经被取消'));
          });
        }
      })
    }

    // 创建 axios 函数
    const context = new Axios({});
    const axios = Axios.prototype.request.bind(context);
    
    // CancelToken 构造函数
    function CancelToken (executor) {
      // 声明一个变量
      var resolvePromise;
      // 为实例对象添加属性
      this.promise = new Promise((resolve) => {
        // 将 resolve 赋值给 resolvePromise 
        resolvePromise = resolve;
      });
      // 调用 executor 函数
      executor(function () {
        // 执行 resolvePromise 函数
        resolvePromise();
      });
    }


    // 获取按钮 验证取消请求实现
    const btns = document.querySelectorAll('button');
    // 声明全局变量
    let cancel = null;
    btns[0].onclick = function () {
      // 检测上一次的请求是否已经完成
      if (cancel !== null) {
        // 取消上一次的请求
        cancel();
      }

      // 创建 cancelToken 的值
      let cancelToken = new axios.CancelToken(
        function (c) {
          // 3. 将 c 的值赋值给 cancel
          cancel = c;
        });
      
      axios({
        method: 'GET',
        url: 'http://localhost:3000/posts',
        // 添加配置对象的属性
        cancelToken: cancelToken
      }).then(response => {
        console.log(response);
        // 将 cancel 的值初始化
        cancel = null;
      });
    }

    // 绑定第二个事件取消请求
    btns[1].onclick = function () {
      cancel();
    }
  </script> 
</body>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue项目中,我们通常会使用axios来发送请求。为了方便管理和维护代码,我们可以将axios请求进行统一封装。 首先,我们需要在项目中安装axios: ``` npm install axios --save ``` 然后,我们可以在src目录下新建一个api目录,用来存放所有的接口请求。在api目录下,我们可以新建一个request.js文件,用来封装axios请求: ``` import axios from 'axios'; // 创建axios实例 const service = axios.create({ baseURL: process.env.BASE_API, // api的base_url timeout: 5000 // 请求超时时间 }); // request拦截器 service.interceptors.request.use(config => { // 在请求发送之前做一些处理 return config; }, error => { // 处理请求错误 console.log(error); Promise.reject(error); }) // respone拦截器 service.interceptors.response.use( response => { // 在接收响应做一些处理,例如统一的错误处理 return response.data; }, error => { console.log('err' + error);// for debug return Promise.reject(error); } ) export default service; ``` 这里我们创建了一个axios实例,并进行了一些配置,例如设置请求超时时间、拦截请求和响应等。并且将其导出,其他地方可以直接引用该实例进行请求。 接下来,我们可以在api目录下新建一个模块,例如user.js,用来存放用户相关的接口请求。在user.js中,我们可以这样写: ``` import request from '@/api/request'; export function login(username, password) { return request({ url: '/user/login', method: 'post', data: { username, password } }) } export function getInfo(token) { return request({ url: '/user/info', method: 'get', params: { token } }) } ``` 这里我们引入了之前封装的axios实例,然后对外导出两个方法login和getInfo,分别用来请求登录和获取用户信息的接口。 最后,我们可以在Vue组件中使用这些接口,例如: ``` import { login, getInfo } from '@/api/user'; export default { name: 'Login', methods: { handleLogin() { login(this.username, this.password).then(response => { // 处理登录成功的逻辑 getInfo(response.token).then(info => { // 处理获取用户信息成功的逻辑 }) }) } } } ``` 这里我们引入了之前定义的login和getInfo方法,并在handleLogin方法中调用它们。需要注意的是,我们在处理登录成功后,还调用了getInfo方法来获取用户信息。这里我们可以看到,我们可以将多个请求串联起来进行处理。 在实际开发中,我们经常会遇到重复请求的问题,例如多次点击提交按钮或者页面切换时进行数据加载等。为了避免重复请求,我们可以对axios进行进一步封装,例如: ``` import axios from 'axios'; // 定义一个空的数组,用来存储每个请求取消函数和标识 const pending = []; const CancelToken = axios.CancelToken; const removePending = (config) => { for (let i = 0; i < pending.length; i++) { if (pending[i].url === config.url + '&' + config.method) { pending[i].cancel(); // 取消重复请求 pending.splice(i, 1); // 删除已经取消请求记录 } } } // 创建axios实例 const service = axios.create({ baseURL: process.env.BASE_API, // api的base_url timeout: 5000 // 请求超时时间 }); // request拦截器 service.interceptors.request.use(config => { // 在请求发送之前做一些处理 removePending(config); config.cancelToken = new CancelToken((c) => { pending.push({ url: config.url + '&' + config.method, cancel: c }); }); return config; }, error => { // 处理请求错误 console.log(error); Promise.reject(error); }) // respone拦截器 service.interceptors.response.use( response => { // 在接收响应做一些处理,例如统一的错误处理 removePending(response.config); return response.data; }, error => { console.log('err' + error);// for debug return Promise.reject(error); } ) export default service; ``` 这里我们定义了一个pending数组,用来存储每个请求取消函数和标识。在每次请求发送之前,我们会先调用removePending函数,用来取消重复请求。在每次请求完成之后,我们会再次调用removePending函数,用来删除已经取消请求记录。这样就可以避免重复请求的问题了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值