[eggjs/egg]如果使用AsyncLocalStorage,如何能够在不被Egg管理的类中,也能正确地拿到上下文对象

2024-06-28 389 views
9

1.Egg里面,大部分的业务代码可能写在了Service、Controller层,这些可以通过继承Egg里面的对应类来完成被Egg管理。这样就能通过this.ctx拿到上下文对象。 2.问题是:如果有很多对象,都是通过new出来的话,就是无法直接从this.ctx拿到上下文。我想通过全局的对象拿到一个上下文。考虑到AsyncLocalStorage。

写法: 1.定义一个storage并暴露出去: const { AsyncLocalStorage } = require('async_hooks'); const storage = new AsyncLocalStorage(); export default storage;

2.中间件里面(按顺序执行的第一个中间件)添加一个Context或者一个uuid也好: import {storage} from './storage' await storage.run(context, async () => await next());

3.在任意的地方,通过拿第一步的storage,再拿到storage存储的内容: import {storage} from './storage' console.log(storage.getStore())

上面的这个写法,对于本地开发下,单次http请求是没有任何问题的,但是我发现,在频率高的情况下,值就窜了,比如uuid。请问这样写是否有问题,以及有没有更好的解决方案或者思路。我在想为何会出现值窜的情况?

回答

3

你好,这个方式应该也需要类继承对应的Application吧,如果是不继承呢,全局任意一个地方可以拿的

7

我也遇到一样的问题,希望ctxStorage能够在任意地方获取到,场景是一些sdk需要拿到当前的上下文ctx。 目前没想到比较好的方法来解决这个问题。 ctxStorage是不是应该设计为在任意地方都能方便地获取到呢?

3

只要拿到 app 就能获取到 app.ctxStorage 了

7

搞一个 Symbol 然后挂到全局类似于 global[Symbol.for('egg#ctxStorage')] ?

6

好像可以哦,就算多个 app 实例,共用一个 als 似乎也是可以正常工作的。