0

我正在尝试创建一个可以添加到任何类的 TypeScript 装饰器,它将创建一个请求范围的上下文,我可以使用它来存储请求 ID。我遇到了几篇关于装饰器的文章,但似乎没有一个适合我的用例。

下面是我用来创建异步钩子、装饰器和应该被包装的示例类的代码。运行代码时,我收到的实际响应是一个空对象。上下文正在丢失,但我不知道为什么。我没有收到任何错误或警告。

任何建议将不胜感激。

这是我用来创建上下文的代码。调用initContext()getContext()函数。

import * as asyncHooks from 'async_hooks'

const contexts: any = {}

asyncHooks.createHook({
  init: (asyncId: any, type: any, triggerAsyncId: any) => {
    if (contexts[triggerAsyncId]) {
      contexts[asyncId] = contexts[triggerAsyncId]
    }
  }
}).enable()

function initContext(fn: any) {
  const asyncResource = new asyncHooks.AsyncResource('REQUEST_CONTEXT')
  return asyncResource.runInAsyncScope(() => {
    const asyncId = asyncHooks.executionAsyncId()
    contexts[asyncId] = {}
    return fn(contexts[asyncId])
  })
}

function getContext() {
  const asyncId = asyncHooks.executionAsyncId()
  return contexts[asyncId] || {}
}

export { initContext, getContext }

这是我用来包装类的装饰器。我试图在函数的上下文中创建构造initContext函数,设置上下文 ID,然后返回新的构造函数。

import { initContext } from './lib/context'

function AsyncHooksContext<T extends { new(...args: any[]): {} }>(target: T) {
  return initContext((context: any) => {
    context.id = 'some-uuid-goes-here'

    return class extends target {
      constructor(...args: any[]) {
        super(...args)
      }
    }
  })
}

export { AsyncHooksContext }

这是一个应该能够生成上下文 ID 的示例类

@AsyncHooksContext
class Foo {
  public bar() {
    const context = getContext()
    console.log('This should be the context => ', { context })
  }
}

new Foo().bar()
4

0 回答 0