vue3基于vant封装XMLHttpRequest 实现流式数据接收、请求超时处理、请求中止处理、二次请求处理、异常处理。
import { Toast } from "vant";
import { getUrlConfig, storage, SortParams } from "@/utils";
export class XHRRequest {
constructor() {
this.url = "";
this.method = "";
this.callBackFn = null;
this.successFn = null;
this.failFn = null;
this.timoutFn = null;
this.againFn = null;
this.timer = null;
this.timeoutNum = 0;
this.token = storage.get("token");
this.source = "h5Teacher";
this.hasStart = false; // 流式返回是否继续
this.isAbort = 0; // 是否终止 0 没有 1有
this.xhr = null;
}
initAjax(url, params, callBackFn, successFn, failFn, againFn) {
this.url = url;
this.params = {
...params,
source: this.source,
token: this.token,
};
this.timeoutNum = 0;
this.callBackFn = callBackFn;
this.successFn = successFn;
this.failFn = failFn;
this.againFn = againFn;
this.xhr = new XMLHttpRequest();
this.xhr.open(
"GET",
`${getUrlConfig().zhujiaoDomain}${url}?${SortParams(this.params)}`,
true,
);
this.xhr.addEventListener("readystatechange", () => {
let { xhr } = this;
if (xhr.readyState === 3 && xhr.status === 200) {
this.hasStart = true;
this.callBackFn && this.callBackFn(xhr.responseText);
} else if (xhr.readyState === 4 && xhr.status === 200) {
this.successFn && this.successFn(xhr.response);
} else if (xhr.readyState === 4 && xhr.status === 500) {
try {
let res = JSON.parse(xhr.response);
// 登录失效处理
if (res.code == 20003) {
storage.clear();
window.location.replace('/home')
} else {
this.failFn && this.failFn(res);
}
} catch (error) {
Toast(xhr.responseText);
}
}
});
this.xhr.addEventListener("abort", (abort) => {
console.log("abort", abort);
this.clearTimer();
});
this.xhr.addEventListener("error", (error) => {
console.log("error", error);
Toast(error);
});
this.xhr.ontimeout = function (e) {
// XMLHttpRequest 超时。在此做某事。
console.log("timout");
};
this.xhr.send();
if (params.requestType == 1 && this.xhr) {
this.checkHasStart();
}
}
checkHasStart() {
this.timer = setInterval(() => {
if (this.hasStart) {
this.clearTimer();
} else {
if (this.timeoutNum >= 10) {
this.clearTimer();
this.xhr.abort();
this.againFn();
} else {
++this.timeoutNum;
}
}
}, 1000);
}
clearTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
this.timeoutNum = 0;
}
}
myAbort() {
this.xhr.abort();
this.xhr = null;
}
}
//--------------------------------应用--------------------------
// 终止请求
const XHRRequestAbortFn = () => {
state.XHRRequestFn && state.XHRRequestFn.myAbort();
};
// 智能生成接口
const getDimScoreTextFn = async (requestType = 1) => {
let params = {
id: props.id,
requestType,
};
const callBackFn = (res) => {
state.commentText = res;
state.showIntelligentCommentResult = true;
};
const successFn = (res) => {
state.commentText = res;
setTimeout(() => {
state.showCursorLine = false;
}, 400);
};
const failFn = () => {
showToast(res.msg);
clickHandle("close");
};
const againAjaxFn = () => {
getDimScoreTextFn(2);
};
state.XHRRequestFn = new XHRRequest();
state.XHRRequestFn.initAjax(
API.GET_DIM_SCORE_TEXT,
params,
callBackFn,
successFn,
failFn,
againAjaxFn,
);
};