目录

问题描述:

问题案例:

问题解决:

1,【原生JS】XMLHttpRequest.abort();

2,【Ajax】ajax.abort(); 

3,【axios】axios.CancelToken;

4,【微信小程序 】RequestTask.abort();

5,【uni-app】 requestTask.abort();


问题描述:

当前端请求发送并且响应未完成时,终止请求,不再返回数据

问题案例:

1,一些列表页接口比较慢,改变查询条件后发送查询请求,这样就和上次的查询请求形成两个异步请求,有时可能就会发生本次请求先得到响应数据,然后上一次请求后得到响应数据,这样在页面上的查询结果就会出现bug。(不是单纯的防抖和节流就能解决问题)

2,一些大文件上传,需要很久的时间,用户在中途想要终止上传

问题解决:

1,【原生JS】XMLHttpRequest.abort();

如果该请求已被发出,XMLHttpRequest.abort() 方法将终止该请求。当一个请求被终止,它的 readyState 属性将被置为0( UNSENT )。示例:

let xhr = new XMLHttpRequest(),
    method = "GET",
    url = "https://developer.mozilla.org/"; // 仅为示例,并非真实接口地址。
xhr.open(method,url,true);

xhr.send();

xhr.abort(); // 终止请求

2,【Ajax】ajax.abort(); 

示例:

let queryTruckAjax;
if(queryTruckAjax){
    queryTruckAjax.abort(); // 终止请求
}
queryTruckAjax =  $.ajax({
    type: "POST",
    url:url,
    dataType: "json",
    success: function(data) {
        do thing...
    },error: function () {
    }
});

3,【axios】axios.CancelToken;

Axios 提供了一个 CancelToken的函数,这是一个构造函数,该函数的作用就是用来取消接口请求的。利用axios请求的config参数,向axios添加一个包含cancelToken的config配置对象。示例:

可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

<body>
<div class="page" id="app">
  <button @click="getMsgFirst" class="get-msg">获取数据1</button>
  <button @click="getMsgSecond" class="get-msg">获取数据2</button>
  <button @click="cancelGetMsg" class="cancel">取消获取</button>
</div>
<script>
  import axios from 'axios'
  var app = new Vue({
    el: '#app',
    data: {
      cancelToken: null, // 这里要先初始化
      source: null, // 这里要先初始化
    },
    created() {
      this.cancelToken = axios.CancelToken;
      this.source = this.cancelToken?.source();
    },
    methods: {
      getMsgFirst () {
        axios.get('/user/12345', {
          cancelToken: this.source?.token
        }).catch(function(thrown) {
          if (axios.isCancel(thrown)) {
            console.log('Request canceled', thrown.message);
          } else {
            // 处理错误
          }
        });
      },

      getMsgSecond () {
        axios.get('/user/12345', {
          cancelToken: this.source?.token
        }).catch(function(thrown) {
          if (axios.isCancel(thrown)) {
            console.log('Request canceled', thrown.message);
          } else {
            // 处理错误
          }
        });
      },

      cancelGetMsg () {
        // 取消请求(message 参数是可选的)
        this.source.cancel('Operation canceled by the user.');
      }
    }
  })
</script>
</body>

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

<body>
  <div class="page" id="app">
    <button @click="getMsg" class="get-msg">获取数据</button>
    <button @click="cancelGetMsg" class="cancel">取消获取</button>
    <ul>
      <li v-for="item in items">{{item.name}}</li>
    </ul>
  </div>
  <script>
  import axios from 'axios'
  var app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!',
      items: [],
      cancel: null // 这里要先初始化
    },
    methods: {
      getMsg () {
        let CancelToken = axios.CancelToken
        let self = this
        // 仅为示例,并非真实接口地址。
        axios.get('http://jsonplaceholder.typicode.com/comments', {
          cancelToken: new CancelToken(c => {
            this.cancel = c
            console.log(c)
            // 这个参数 c 就是CancelToken构造函数里面自带的取消请求的函数,这里把该函数当参数用
          })
        }).then(res => {
          this.items = res.data
        }).catch(err => {
          console.log(err)
        })
      },

      cancelGetMsg () {
        this.cancel() // 终止请求
      }
    }
  })
  </script>
</body>

实例化后的 axios 访问不到 CancelToken,但是你可以这样做:

import { Axios } from '@/common'
import axios from 'axios'
export let cancelAnalysisTask = null

// 解析excel
export const analysis = (option = {}) => Axios.post('/get/list', option, {
  cancelToken: new axios.CancelToken(c => { // 这里的CancelToken原生的axios上的
    cancelAnalysisTask = c
  })
})

4,【微信小程序 】RequestTask.abort();

示例:

if (requestTask) {
    requestTask.abort(); // 终止请求
}
let requestTask = wx.request({
  url: 'test.php', //仅为示例,并非真实的接口地址
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success (res) {
    console.log(res.data)
  }
})

5,【uni-app】 requestTask.abort();

如果希望返回一个 requestTask 对象,需要至少传入 success / fail / complete 参数中的一个,如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象。示例:

const requestTask = uni.request({
    url: 'https://www.example.com/request', // 仅为示例,并非真实接口地址。
    data: {
        name: 'name',
        age: 18
    },
    success: function(res) {
        console.log(res.data);
    }
});

 // 终止请求
requestTask.abort();