js - 取消接口請求


js - 取消接口請求

axios - cancelToken

參考資料

axios
axios 之cancelToken原理以及使用
axios取消接口請求
axios中斷請求cancelToken

use

CancelToken.source

可以使用 CancelToken.source 工廠方法創建 cancel token,像這樣:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {//get請求在第二個參數
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 處理錯誤
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token//post請求在第三個參數
})

// 取消請求(message 參數是可選的)
source.cancel('Operation canceled by the user.');

構造函數

還可以通過傳遞一個 executor 函數到 CancelToken 的構造函數來創建 cancel token:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函數接收一個 cancel 函數作為參數
    cancel = c;
  })
});

// cancel the request
cancel();

notice

  1. 可以使用同一個 cancel token 取消多個請求
  2. source.cancel函數執行后,會永久取消請求(如何取消攔截?)
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {//get請求在第二個參數
  cancelToken: source.token // 1. 使用同一個 cancel token 取消多個請求
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 處理錯誤
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, { //post請求在第三個參數
  cancelToken: source.token // 1. 使用同一個 cancel token 取消多個請求
})

// 取消請求(message 參數是可選的)
source.cancel('Operation canceled by the user.'); // 2. source.cancel函數執行后,會永久取消請求

如何取消攔截

使用構造函數創建 cancel token,每次請求使用不同的 cancel token,請求前執行前一個cancel token

eg:重復請求只執行最后一次

<template>
  <div>
    <el-button @click="login">login</el-button>
    <el-button @click="forLogin">forLogin</el-button>
  </div>
</template>

<script>
import axios from 'axios';
const CancelToken = axios.CancelToken;
import { getToken } from '@/utils/cookies'; // get token from cookie
export default {
  async mounted() {},
  methods: {
    CancelToken() {},
    forLogin() {
      for (let i in Array(5).fill('')) {
        this.login();
      }
    },
    async login() {
      try {
        this.cancelToken();
        const res = await this.$Request({
          url: `${
            this.$store.state.config.loginCenterBaseUrl
          }/api/v2/user/${getToken()}`,
          //   cancelToken: source.token,
          cancelToken: new CancelToken((cancel) => {
            this.cancelToken = cancel;
          }),
        });
        this.cancelToken = () => {};
        console.log('sucess:', res);
      } catch (err) {
        if (axios.isCancel(err)) {
          console.error('Request canceled', err.message);
        } else {
          // 處理錯誤
          console.error(err);
        }
      }
    },
  },
};
</script>

重復點擊問題***

開發的時候會遇到一個重復點擊的問題,短時間內多次點擊同一個按鈕發送請求會加重服務器的負擔,消耗瀏覽器的性能,多以絕大多數的時候我們需要做一個取消重復點擊的操作

axios攔截器

    import axios from 'axios';
    
    axios.defaults.timeout = 5000;
    axios.defaults.baseURL ='';

    let pending = []; //聲明一個數組用於存儲每個ajax請求的取消函數和ajax標識
    let cancelToken = axios.CancelToken;
    let removePending = (ever) => {
        for(let p in pending){
            if(pending[p].u === ever.url + '&' + ever.method) { //當當前請求在數組中存在時執行函數體
                pending[p].f(); //執行取消操作
                pending.splice(p, 1); //把這條記錄從數組中移除
            }
        }
    }
    
    //http request 攔截器
    axios.interceptors.request.use(
    config => {
      config.data = JSON.stringify(config.data);
      config.headers = {
        'Content-Type':'application/x-www-form-urlencoded'
      }
      // ------------------------------------------------------------------------------------
      removePending(config); //在一個ajax發送前執行一下取消操作
      config.cancelToken = new cancelToken((c)=>{
         // 這里的ajax標識我是用請求地址&請求方式拼接的字符串,當然你可以選擇其他的一些方式
         pending.push({ u: config.url + '&' + config.method, f: c });  
      });
      // -----------------------------------------------------------------------------------------
      return config;
    },
    error => {
      return Promise.reject(err);
    }
  );
  //http response 攔截器
  axios.interceptors.response.use(
    response => {
      // ------------------------------------------------------------------------------------------
      removePending(res.config);  //在一個ajax響應后再執行一下取消操作,把已經完成的請求從pending中移除
      // -------------------------------------------------------------------------------------------
      if(response.data.errCode ==2){
        router.push({
          path:"/login",
          querry:{redirect:router.currentRoute.fullPath}//從哪個頁面跳轉
        })
      }
      return response;
    },
    error => {
      return Promise.reject(error)
    }
  )

原生js - abort()

  <body>
    <div class="page" id="app">
      <button class="get-msg">獲取數據</button>
      <button class="cancel">取消獲取</button>
    </div>
    <script>
      var currentAjax = null;
      $('.get-msg').click(function () {
        currentAjax = $.ajax({
          type: 'GET',
          url: 'http://jsonplaceholder.typicode.com/comments',
          success: function (res) {
            console.log(res);
          },
          error: function (err) {
            console.log('獲取失敗');
          },
        });
      });
      $('.cancel').click(function () {
        if (currentAjax) {
          currentAjax.abort();
        }
      });
    </script>
  </body>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM