Browse Source

feat: http插件更新

v7
谢亚昕 4 months ago
parent
commit
c91ebc3eb3
  1. 66
      src/plugins/http/base.ts
  2. 43
      src/plugins/http/index.ts
  3. 74
      src/plugins/http/plugins/Loading.ts

66
src/plugins/http/base.ts

@ -25,6 +25,11 @@ export class Plugin implements IPlugin {
destory() { }
}
export const enum EFor {
Continue,
Break,
}
export abstract class PluginsManager {
static plugins: IPlugin[] = []
static use(plugin: IPlugin | IPlugin[]) {
@ -34,28 +39,44 @@ export abstract class PluginsManager {
}
plugins: IPlugin[] = []
exculdPlugins: string[] = []
use(plugin: IPlugin) {
if (Array.isArray(plugin)) {
this.plugins = this.plugins.concat(plugin)
} else this.plugins.push(plugin)
}
callPluginByName<T>(name: string, key: keyof T, ...argus: any[]) {
async runPlugins(cb: (p: IPlugin) => Promise<EFor | undefined>) {
const array = [...PluginsManager.plugins, ...this.plugins]
for (let i = 0; i < array.length; i++) {
let p = array[i]
let result = await cb(p)
if (result === EFor.Continue) {
continue
} else if (result === EFor.Break) {
break
}
}
}
async _callPluginByName<T>(name: string, key: keyof T, ...argus: any[]) {
const array = [...PluginsManager.plugins, ...this.plugins]
for (let i = 0; i < array.length; i++) {
let p = array[i]
if (this.exculdPlugins.includes(p.name)) continue
if (!p.name) continue
if (name === p.name) {
const fn = (p as T)[key]
typeof fn === "function" && fn.apply(p, argus)
typeof fn === "function" && await fn.apply(p, argus)
}
}
}
callPlugin(key: keyof IPlugin, ...argus: any[]) {
async _callPlugin(key: keyof IPlugin, ...argus: any[]) {
const array = [...PluginsManager.plugins, ...this.plugins]
for (let i = 0; i < array.length; i++) {
let p = array[i]
if (this.exculdPlugins.includes(p.name)) continue
const fn = p[key]
typeof fn === "function" && fn.apply(p, argus)
typeof fn === "function" && await fn.apply(p, argus)
}
}
}
@ -66,24 +87,45 @@ export abstract class httpBase extends PluginsManager {
requestInterceptorId: null | number = null
responseInterceptorId: null | number = null
async callPluginByName<T>(name: string, key: keyof T, ...argus: any[]) {
await this.runPlugins(async (p) => {
if (this.exculdPlugins.includes(p.name)) return EFor.Continue
if (!p.name) return EFor.Continue
if (name === p.name) {
const fn = (p as T)[key]
typeof fn === "function" && await fn.apply(p, argus)
}
})
// await this._callPluginByName<T>(name, key, ...argus)
}
async callPlugin(key: keyof IPlugin, ...argus: any[]) {
await this.runPlugins(async (p) => {
if (this.exculdPlugins.includes(p.name)) return EFor.Continue
const fn = p[key]
typeof fn === "function" && await fn.apply(p, argus)
})
// await this._callPlugin(key, ...argus)
}
create<T>(config?: CreateAxiosDefaults<T>) {
this.instance = axios.create(deepAssign<CreateAxiosDefaults<T>>(axios.defaults, config ?? {}))
this.requestInterceptorId = this.instance.interceptors.request.use(config => {
this.requestInterceptorId = this.instance.interceptors.request.use(async config => {
const argu = { config }
this.callPlugin("beforeRequestConfig", argu)
await this.callPlugin("beforeRequestConfig", argu)
return argu.config
}, error => {
}, async error => {
const argu = { error }
this.callPlugin("beforeRequestError", argu)
await this.callPlugin("beforeRequestError", argu)
return Promise.reject(argu.error)
})
this.responseInterceptorId = this.instance.interceptors.response.use(response => {
this.responseInterceptorId = this.instance.interceptors.response.use(async response => {
const argu = { response }
this.callPlugin("beforeResponse", argu)
await this.callPlugin("beforeResponse", argu)
return Promise.resolve(argu.response)
}, (error) => {
}, async (error) => {
const argu = { error }
this.callPlugin("beforeResponseError", argu)
await this.callPlugin("beforeResponseError", argu)
return Promise.reject(argu.error)
})
return this.instance

43
src/plugins/http/index.ts

@ -3,6 +3,15 @@ import { CreateAxiosDefaults, AxiosRequestConfig, AxiosResponse } from "axios"
const FlyPoll: Map<string, any> = new Map()
interface ICallFly {
pass: (argus: { exculdPlugins?: string[] }) => Fly
get: <T = any, Data = unknown>(...argus: [url: string, config?: AxiosRequestConfig<Data> | undefined]) => () => Promise<AxiosResponse<T>>
post: <T = any, Data = unknown>(...argus: [url: string, config?: AxiosRequestConfig<Data> | undefined]) => () => Promise<AxiosResponse<T>>
put: <T = any, Data = unknown>(...argus: [url: string, config?: AxiosRequestConfig<Data> | undefined]) => () => Promise<AxiosResponse<T>>
delete: <T = any, Data = unknown>(...argus: [url: string, config?: AxiosRequestConfig<Data> | undefined]) => () => Promise<AxiosResponse<T>>
request: <T = any, Data = unknown>(...argus: [config: AxiosRequestConfig<Data>]) => () => Promise<AxiosResponse<T>>
}
class Fly extends httpBase {
static disposeAll() {
if (FlyPoll.size) {
@ -32,8 +41,25 @@ class Fly extends httpBase {
if (!instance) {
throw new Error("未初始化此实例")
}
instance.exculdPlugins = []
return instance
}
static callFn(name?: string): ICallFly {
if (!name) name = "$defalut"
const instance = FlyPoll.get(name)
if (!instance) {
throw new Error("未初始化此实例")
}
instance.exculdPlugins = []
return new Proxy(instance, {
get(target, p: string) {
if (["get", "post", "put", "delete", "request"].includes(p.toLowerCase())) {
return (...argus: any[]) => () => target[p](...argus)
}
return target[p]
},
})
}
static get method() {
return {
@ -59,6 +85,11 @@ class Fly extends httpBase {
}
}
pass({ exculdPlugins }: { exculdPlugins?: string[] }) {
this.exculdPlugins = exculdPlugins ?? []
return this
}
name: string
constructor(name: string) {
@ -80,15 +111,15 @@ class Fly extends httpBase {
request<T = any, Data = unknown>(...argus: [config: AxiosRequestConfig<Data>]) {
return this.instance!.request.apply(this.instance, argus) as Promise<AxiosResponse<T>>
}
#init(config: AxiosRequestConfig) {
this.callPlugin("beforeCreate")
async #init(config: AxiosRequestConfig) {
await this.callPlugin("beforeCreate")
this.create(config)
this.callPlugin("created")
await this.callPlugin("created")
}
#destory() {
this.callPlugin("beforeDestory")
async #destory() {
await this.callPlugin("beforeDestory")
this.destory()
this.callPlugin("destory")
await this.callPlugin("destory")
}
}

74
src/plugins/http/plugins/Loading.ts

@ -12,13 +12,15 @@ type AxiosRequestConfigPlus = AxiosRequestConfig & {
$loading_ToastID?: Id
$loading_CreateTimeStamp?: number
$loading_ToastShowFn?: () => void
$loading_ToastHideFn?: () => void
$loading_ShowTimerId?: NodeJS.Timeout
}
interface IConfig {
text: string
min: number
minShow: boolean
minSync: boolean
minShowLong: number
}
// 取消重复请求
@ -30,6 +32,8 @@ export class LoadingPlugin implements IPlugin {
text: "加载中",
min: 1000,
minShow: false,
minSync: true,
minShowLong: 1000,
}
config: IConfig = JSON.parse(JSON.stringify(this.defaultConfig))
@ -62,36 +66,68 @@ export class LoadingPlugin implements IPlugin {
if (!this.getConfig("minShow", config.loadingAttrs)) {
config.$loading_ToastShowFn()
delete config.$loading_ToastShowFn
} else {
config.$loading_ShowTimerId = setTimeout(() => {
config.$loading_ToastShowFn!()
delete config.$loading_ToastShowFn
}, this.getConfig("min", config.loadingAttrs));
}
}
beforeResponse({ response }: { response: AxiosResponse }) {
const { config } = response as { config: AxiosRequestConfigPlus }
if (!this.getConfig("minShow", config.loadingAttrs)) {
const min = this.getConfig("min", config.loadingAttrs)
if (config.$loading_ToastID) {
const [ToastID, showTimeStamp] = [config.$loading_ToastID, config.$loading_CreateTimeStamp]
const oft = new Date().getTime() - showTimeStamp!
if (oft < min) {
setTimeout(() => {
return new Promise((resolve) => {
const over = (isOver: boolean) => {
if (isOver) {
resolve(void 0)
}
}
const { config } = response as { config: AxiosRequestConfigPlus }
clearTimeout(config.$loading_ShowTimerId)
if (!this.getConfig("minShow", config.loadingAttrs)) {
const min = this.getConfig("min", config.loadingAttrs)
if (config.$loading_ToastID) {
const [ToastID, showTimeStamp] = [config.$loading_ToastID, config.$loading_CreateTimeStamp]
const oft = new Date().getTime() - showTimeStamp!
if (oft < min) {
setTimeout(() => {
toast.dismiss(ToastID)
over(this.getConfig("minSync", config.loadingAttrs))
}, min - oft);
} else {
over(this.getConfig("minSync", config.loadingAttrs))
toast.dismiss(ToastID)
}
delete config.$loading_ToastID
delete config.$loading_CreateTimeStamp
}
} else {
if (config.$loading_ToastID) {
const min = this.getConfig("minShowLong", config.loadingAttrs)
const [ToastID, showTimeStamp] = [config.$loading_ToastID, config.$loading_CreateTimeStamp]
const oft = new Date().getTime() - showTimeStamp!
if (oft < min) {
setTimeout(() => {
toast.dismiss(ToastID)
over(this.getConfig("minSync", config.loadingAttrs))
}, min - oft);
} else {
over(this.getConfig("minSync", config.loadingAttrs))
toast.dismiss(ToastID)
}, min - oft);
} else {
toast.dismiss(ToastID)
}
delete config.$loading_ToastID
delete config.$loading_CreateTimeStamp
}
delete config.$loading_ToastID
delete config.$loading_CreateTimeStamp
}
} else {
}
over(!this.getConfig("minSync", config.loadingAttrs))
})
}
beforeResponseError(argu: { error: AxiosError }) {
const requestConfig = argu.error.config! as AxiosRequestConfigPlus
clearTimeout(requestConfig.$loading_ShowTimerId)
if (requestConfig.$loading_ToastID) {
const [ToastID] = requestConfig.$loading_ToastID.split("$")
const [ToastID] = [requestConfig.$loading_ToastID, requestConfig.$loading_CreateTimeStamp]
toast.dismiss(ToastID)
delete requestConfig.$loading_ToastID
delete requestConfig.$loading_CreateTimeStamp
}
}
}

Loading…
Cancel
Save