/**
* @description
* axios 并发请求处理竞态,
* (注意这个类不能直接使用,是对 axios 的封装)
* @example
* // 使用
* let axiosRace = new AxiosRace({ blockAfter: true });
* // url: 请求地址
* // config: axios 请求配置
* axiosRace.request(url, config)
*/
class AxiosRace {
#preCancelTokenSource = null;
#firstRequest = null;
hasFirstRequest = false;
/**
* @param {Object} options - 配置项。
* @param {Boolean} options.cancelBefore - 取消之前的请求,只有最后一个请求有效。
* @param {Boolean} options.blockAfter - 后面的请求不执行,并返回第一个请求的结果。
*/
constructor (options) {
const { blockAfter, cancelBefore } = options
if (cancelBefore) {
this.request = this.#requestCancelBefore
return
}
if (blockAfter) {
this.request = this.#requestBlockAfter
return
}
throw new Error('please provide the correct options')
}
// 取消之前的请求,只有最后一个请求有效
#requestCancelBefore (url, config) {
const axiosConfig = {
...config
}
// 取消上一次请求
if (this.#preCancelTokenSource) {
this.#preCancelTokenSource.cancel()
}
// 创建 cancel token
const source = CancelToken.source()
axiosConfig.cancelToken = source.token
// 存储 cancel token
this.#preCancelTokenSource = source
return axios.request(url, axiosConfig).finally(() => {
this.#preCancelTokenSource = null
})
}
// 后面的请求不执行,并返回第一个请求的结果
#requestBlockAfter (url, config) {
// 返回第一次请求的结果
if (this.#firstRequest) {
return this.#firstRequest
}
this.#firstRequest = axios.request(url, config).finally(() => {
this.#firstRequest = null
this.hasFirstRequest = false
})
this.hasFirstRequest = true
return this.#firstRequest
}
}
export { AxiosRace }