请求处理
- 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 => res.text()).then(text => {
// text 就是返回内容
});
});