Closed caihaibin1991 closed 4 years ago
同时,该方式,在js转型成ts时,变量可以正常传递,解决session值无法在js里获取的问题。
// import { current } from 'node-zone'
const {current} = require('node-zone');
// a zone has a name, a parent, and data
console.log(
current.name, // "<root>"
current.parent, // null
current.data // { __proto__: null }
)
// create a new child zone
const myZone = current.fork('my zone')
console.log(
myZone.name, // "my zone"
myZone.parent, // current
myZone.data // { __proto__: current.data }
)
// run some code in it
myZone.run(() => {
console.log(current.name) // "my zone"
// zone is preserved in async functions
process.nextTick(() => {
console.log(current.name) // "my zone"
})
});
(async function () {
// return;
// run some code in it
myZone.run(async () => {
const {current} = require('node-zone');
console.log(current.name) // "my zone"
// zone is preserved in async functions
process.nextTick(() => {
console.log(current.name) // "my zone"
})
})
})();
console.log(current.name) // "<root>"
目前是直接在中间件里使用,然后全局任意地方直接从“线程作用域”中取值。减少参数传递
/src/app/middleware/commonRequest.ts
// import {Context} from 'egg';
import * as querystring from 'querystring';
import {v4} from 'uuid';
import {Context, EggAppConfig} from 'egg';
export default function (options: EggAppConfig['uuid']) {
return async (ctx: Context, next: any): Promise<void> => {
const name = ctx.app.config.uuid.name;
let uuid = ctx.cookies.get(name, {signed: true});
if (!uuid || uuid === 'null') {
uuid = v4();
ctx.cookies.set(name, uuid, {
signed: true,
maxAge: options.maxAge,
});
}
ctx.locals.uuid = uuid;
ctx.session._id = uuid;
//解析出get的参数
let query = ctx.originalUrl;
if (!ctx.params) {
ctx.params = {};
}
if (globalThis.common.stringHelper.stristr(query, '?')) {
query = query.replace(/^.+\?/, '');
let params = querystring.parse(query);
ctx.params = Object.assign(params, ctx.params);
}
ctx.params = Object.assign(ctx.params, ctx.request.body);
//取消注释会报错
//@ts-ignore
//ctx.db = ctx.model.Admin['SystemConfig'].db.db;
try {
const {current} = require('node-zone');
let zone = current.fork(ctx.getSessReqKey());
await zone.run(async function () {
await next();
});
//全局日志记录
const service = await ctx.requestContext.getAsync('admin/AdminLogService');
service.record();
} catch (e) {
e = globalThis.gctx.parse(e);
if (e && e.message.indexOf('Validation Failed') != -1 && e.errors && globalThis.common.isArray(e.errors) && e.errors.length) {
return ctx.failure(ctx.__(e.errors[0].field) + '' + e.errors[0].message, e.errors);
}
//全局日志记录
const service = await ctx.requestContext.getAsync('admin/AdminLogService');
service.record(e.message);
//异常捕获
throw e;
}
if (!ctx.body) {
throw new Error('响应内容为空或不存在,请检查控制器内容!');
}
};
}
没太明白。。。这个希望达成啥效果?
当前的上下文全部是围绕ctx, 但是在js重写成ts过程中,原来封装的大量库,大量函数,是无法直接读取到这个变量的。这样会出现个问题,如果js逐渐调整成ts里,一次性需要改动的工作量太大。很多地方需要扩展一个上下文变量。如果使用node-zone模块,可以在中间件启动这个“作用域”,任何地方直接: 存值:
const {current} = require('node-zone');
current.data['my_data'] =1;
取值:
const {current} = require('node-zone');
console.log(current.data['my_data']);
目前测试了瞬间1000次异步请求,多层嵌套混合读写,都能正常写和读。异步和同步线程,都可以很好的传递变量到深层。真的方便了很多。 这边在尝试启用中,想咨询async_hooks是否有什么影响这边没注意到。然后如果这个东西确实可以这么使用。这边再封装一个中间件进行读写。
目前 async_hooks 有性能影响,20%~50% 不等,中后台问题不大。
好的。谢谢。这边做下特殊处理。封装成单独中间件。避免没必要的性能消耗。[握手]
midway 之前在 pandora 时期也是用的 async_hooks,后来觉得性能还是有一些影响,链路追踪设计了 IoC 的 requestContainer,减少了性能消耗。
好的。谢谢
https://www.npmjs.com/package/node-zone 通过该模块,实现了变量保存到"线程作用域"中,js在任意嵌套的情况下,可以通过简单的current.data.xx形式读取变量。 这边测试目前没发现什么问题,想了解下,这块东西是否会出现什么其它的冲突问题?该模块使用了 async_hooks.