export class ServiceError extends Error { code?: number origin?: string constructor(message: string, origin?: string, code?: number) { super(message) this.code = code this.origin = origin this.stack = `${this.message}\n${this.origin}\n${this.code || ''}` } toString() { return this.message } } export class Service { throw(message: string, origin?: string, code?: number) { throw new ServiceError(message, origin, code) } } export function injectable (Ctor: T) { let instance!: any return new Proxy(Ctor, { construct(t, args) { if (!instance) { instance = new Ctor(args) // console.log('instance ' + Ctor.name) } return instance } }) } const runnerMap: { [key: string]: ((_res: any) => void)[] | undefined } = {} /** * 互斥注解 * 用于保证某个方法同一时间只有单次调用 */ export function mutex(target: any, property: string) { const oriFn = target[property] const funcKey = `${target.constructor.name}-${property}` Object.defineProperty(target, property, { async value(...args: any[]) { const key = funcKey + JSON.stringify(args) if (runnerMap[key]) { return await new Promise((res) => { runnerMap[key]?.push((result: any) => res(result)) }) } runnerMap[key] = [] setTimeout(() => { runnerMap[key] = undefined }, 4000) const res = await Reflect.apply(oriFn, this, args || []) runnerMap[key]?.forEach((fn) => fn(res)) runnerMap[key] = undefined return res } }) return target[property] }