跳到主要内容

中断请求

2024年04月09日
柏拉文
越努力,越幸运

一、Ajax


function normalizeUrl(url, params) {
let queryString = Object.keys(params).reduce((prev, key) => {
return (prev += `${key}=${params[key]}&`);
}, "?");
return url + queryString.slice(0, queryString.length - 1);
}

function normalizeToFormUrlencoded(params) {
const searchParams = new URLSearchParams();
Object.keys(params).forEach((key) => {
searchParams.append(key, params[key]);
});
return searchParams.toString();
}

function normalizeToFormData(params) {
const formData = new FormData();
Object.keys(params).forEach((key) => {
formData.append(key, params[key]);
});
return formData;
}

function normalizeToJson(params) {
return JSON.stringify(params);
}

function normalizeBody(headers, params) {
if (!headers) {
return normalizeToJson(params);
}
const contentType =
headers["Content-Type"] ||
headers["Content-type"] ||
headers["content-type"];
if (!contentType || contentType === "application/json") {
return normalizeToJson(params);
} else if (contentType === "x-www-form-urlencoded") {
return normalizeToFormUrlencoded(params);
} else {
return normalizeToFormData(params);
}
}

function request(url, method, params, headers) {
let ajax = new XMLHttpRequest();
const baseRequest = () => {
return new Promise((resolve, reject) => {
const normalizeMethod = method.toUpperCase();
const normalizedUrl =
normalizeMethod === "GET" ? normalizeUrl(url, params) : url;
ajax.open(normalizeMethod, normalizedUrl);
ajax.addEventListener("readystatechange", function () {
if (ajax.readyState === 4 && [200, 304].includes(ajax.status)) {
return resolve(JSON.parse(ajax.responseText));
}
});
ajax.addEventListener("error", function () {
return reject("请求已出错");
});
ajax.addEventListener("abort", function () {
return reject(`请求已中断`);
});
const normalizedBody =
normalizeMethod === "GET" ? null : normalizeBody(headers, params);
ajax.send(normalizedBody);
});
};
return {
ajax,
run: baseRequest,
};
}

const { ajax, run } = request("http://test.bolawen.com/server/async", "post", {
a: 1,
b: 2,
});
run()
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});

setTimeout(() => {
ajax.abort();
}, 3000);

二、Axios


function request(url, method, params, signal) {
const normalizeMethod = method.toUpperCase();
const normalizedOptions = {
method,
signal: signal,
params: normalizeMethod === "GET" ? params : null,
body: normalizeMethod === "GET" ? null : params,
};
return axios({
url,
method: normalizeMethod,
...normalizedOptions,
})
.then((res) => {
if (res.status === 200) {
return Promise.resolve(res.data);
}
return Promise.reject(res.statusText);
})
.catch((error) => {
if (typeof error === "object") {
return Promise.reject(`错误类型为: ${error.name}, 具体原因: ${error}`);
}
return Promise.reject(error);
});
}

const controller = new AbortController();
const signal = controller.signal;
request("http://test.bolawen.com/server/async", "post", { a: 1, b: 2 }, signal)
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});
setTimeout(() => {
controller.abort();
}, 3000);

三、Fetch


function normalizeUrl(url, params) {
let queryString = Object.keys(params).reduce((prev, key) => {
return (prev += `${key}=${params[key]}&`);
}, "?");
return url + queryString.slice(0, queryString.length - 1);
}

function request(url, method, params, header, signal) {
const normalizeMethod = method.toUpperCase();
const normalizedUrl =
normalizeMethod === "GET" ? normalizeUrl(url, params) : url;
const normalizedOptions = {
method,
signal: signal,
body: normalizeMethod === "GET" ? null : JSON.stringify(params),
};
return fetch(normalizedUrl, {
method: normalizeMethod,
...normalizedOptions,
})
.then((res) => {
if (res.ok) {
return res.json();
}
return Promise.reject(res.statusText);
})
.catch((error) => {
if (typeof error === "object") {
return Promise.reject(`错误类型为: ${error.name}, 具体原因: ${error}`);
}
return Promise.reject(error);
});
}

const controller = new AbortController();
const signal = controller.signal;
request(
"http://test.bolawen.com/server/async",
"post",
{ a: 1, b: 2 },
null,
signal
)
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});

setTimeout(() => {
controller.abort();
}, 3000);