Skip to main content

请求处理

  • ajax
  • fetch

如何取消请求?

  • xhr.abort
  • AbortController api

axios 请求函数示例:

 import type { AxiosRequestConfig } from "axios";
 ​
 // 用于存储每个请求的标识和取消函数
 const pendingMap = new Map<string, AbortController>();
 ​
 const getPendingUrl = (config: AxiosRequestConfig): string => {
   return [config.method, config.url].join("&");
 };
 ​
 export class AxiosCanceler {
   /**
    * 添加请求
    * @param config 请求配置
    */
   public addPending(config: AxiosRequestConfig): void {
     this.removePending(config);
     const url = getPendingUrl(config);
     const controller = new AbortController();
     config.signal = controller.signal;
     if (!pendingMap.has(url)) {
       // 如果当前请求不在等待中,将其添加到等待中
       pendingMap.set(url, controller);
    }
  }
 ​
   /**
    * 清除所有等待中的请求
    */
   public removeAllPending(): void {
     pendingMap.forEach((abortController) => {
       if (abortController) {
         abortController.abort();
      }
    });
     this.reset();
  }
 ​
   /**
    * 移除请求
    * @param config 请求配置
    */
   public removePending(config: AxiosRequestConfig): void {
     const url = getPendingUrl(config);
     if (pendingMap.has(url)) {
       // 如果当前请求在等待中,取消它并将其从等待中移除
       const abortController = pendingMap.get(url);
       if (abortController) {
         abortController.abort(url);
      }
       pendingMap.delete(url);
    }
  }
 ​
   /**
    * 重置
    */
   public reset(): void {
     pendingMap.clear();
  }
 }

axios 底层还是基于 abort 来实现,源码分析参考 https://github.com/GitHubJackson/sc.js/issues/3

ajax 取消请求示例

function getWithCancel(url, token) { // the token is for cancellation
var xhr = new XMLHttpRequest;
xhr.open("GET", url);
return new Promise(function(resolve, reject) {
xhr.onload = function() { resolve(xhr.responseText); });
token.cancel = function() { // SPECIFY CANCELLATION
xhr.abort(); // abort request
reject(new Error("Cancelled")); // reject the promise
};
xhr.onerror = reject;
});
};

fetch 示例

const data = {};
// 构造器对象
let controller = null;

// 按钮点击
button.addEventListener('click', function (event) {
// 构造 AbortController 对象
if (data.controller) {
controller = data.controller;
} else {
controller = new AbortController();
data.controller = controller;
}
// 如果正在请求,终止
if (data.loading) {
controller.abort();
// 构建新的 AbortController
controller = new AbortController();
data.controller = controller;
}
data.loading = true;

// 请求逻辑
fetch('./getVal.php?val=' + event.target.value, {
signal: controller.signal
}).then(res =&gt; res.text()).then(text =&gt; {
// text 就是返回内容
});
});