service.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. export class ServiceError extends Error {
  2. code?: number
  3. origin?: string
  4. constructor(message: string, origin?: string, code?: number) {
  5. super(message)
  6. this.code = code
  7. this.origin = origin
  8. this.stack = `${this.message}\n${this.origin}\n${this.code || ''}`
  9. }
  10. toString() {
  11. return this.message
  12. }
  13. }
  14. export class Service {
  15. throw(message: string, origin?: string, code?: number) {
  16. throw new ServiceError(message, origin, code)
  17. }
  18. }
  19. export function injectable<T extends { new(..._args: any[]): {} }> (Ctor: T) {
  20. let instance!: any
  21. return new Proxy(Ctor, {
  22. construct(t, args) {
  23. if (!instance) {
  24. instance = new Ctor(args)
  25. // console.log('instance ' + Ctor.name)
  26. }
  27. return instance
  28. }
  29. })
  30. }
  31. const runnerMap: { [key: string]: ((_res: any) => void)[] | undefined } = {}
  32. /**
  33. * 互斥注解
  34. * 用于保证某个方法同一时间只有单次调用
  35. */
  36. export function mutex(target: any, property: string) {
  37. const oriFn = target[property]
  38. const funcKey = `${target.constructor.name}-${property}`
  39. Object.defineProperty(target, property, {
  40. async value(...args: any[]) {
  41. const key = funcKey + JSON.stringify(args)
  42. if (runnerMap[key]) {
  43. return await new Promise((res) => {
  44. runnerMap[key]?.push((result: any) => res(result))
  45. })
  46. }
  47. runnerMap[key] = []
  48. setTimeout(() => {
  49. runnerMap[key] = undefined
  50. }, 4000)
  51. const res = await Reflect.apply(oriFn, this, args || [])
  52. runnerMap[key]?.forEach((fn) => fn(res))
  53. runnerMap[key] = undefined
  54. return res
  55. }
  56. })
  57. return target[property]
  58. }