我想在NestJs 拦截器中使用AsyncLocalStorage:
export interface CallHandler<T = any> {
handle(): Observable<T>;
}
export interface NestInterceptor<T = any, R = any> {
intercept(context: ExecutionContext, next: CallHandler<T>): Observable<R> | Promise<Observable<R>>;
}
Run Code Online (Sandbox Code Playgroud)
拦截器函数获取 anext CallHandler返回一个Observable。
在这种情况下我不能使用run(运行回调将在callHandler.handle()可观察对象完成之前立即退出):
intercept(context: ExecutionContext, callHandler: CallHandler): Observable<any> | Promise<Observable<any>> {
const asyncLocalStorage = new AsyncLocalStorage();
const myStore = { some: 'data'};
return asyncLocalStorage.run(myStore, () => callHandler.handle());
}
Run Code Online (Sandbox Code Playgroud)
我想出的解决方案是这样的:
const localStorage = new AsyncLocalStorage();
export class MyInterceptor …Run Code Online (Sandbox Code Playgroud) 我一直在探索async_hooksAPI 以跟踪异步事件中的状态。我发现destroy并不总是为每个相应的init回调调用回调。
这是一个简单的重现:
const asyncHooks = require("async_hooks");
const fs = require("fs");
const https = require("https");
asyncHooks
.createHook({
init(asyncId, type, triggerId) {
fs.writeSync(1, `init ${asyncId} ${triggerId} ${type}\n`);
},
destroy(asyncId) {
fs.writeSync(1, `destroy ${asyncId}\n`);
},
promiseResolve(asyncId) {
fs.writeSync(1, `promiseResolve ${asyncId}\n`);
}
})
.enable();
https.get("https://www.google.com", res => {
console.log("status code - " + res.statusCode);
});
Run Code Online (Sandbox Code Playgroud)
当发出一个简单的 HTTP 请求时,上面记录了所有的init和destroy回调。
这是输出:
$ node bug.js
* init 5 1 TCPWRAP
* init 6 1 TLSWRAP
init …Run Code Online (Sandbox Code Playgroud) 广泛地说,在 NodeJS 中,每当代码运行时,程序都会创建“异步上下文”,并通过事件循环或微任务队列创建稍后运行的回调。网络请求、setTimeout回调、Promise 等。
在现代版本的 NodeJs 中,您可以使用(仍处于实验阶段)async_hooks模块来跟踪这些异步资源的生命周期。
以前版本的 NodeJS 已经弃用了process.addAsyncListener——通过polyfillasync-listener包保持活力。
Deno 是否有任何内置或第三方功能允许用户态代码跟踪这些异步上下文的创建?或者 Deno 的工作原理是否有什么因素使得它成为一个无关紧要的概念?
我正在尝试将 Snowflake 集成到我的 Cypress 测试中,但它在编译时不断抛出错误。错误:
Error: Webpack Compilation Error
./node_modules/vm2/lib/resolver-compat.js
Module not found: Error: Can't resolve 'async_hooks' in 'C:\snowflake\node_modules\vm2\lib'
resolve 'async_hooks' in 'C:\snowflake\node_modules\vm2\lib'
Parsed request is a module
using description file: C:\snowflake\node_modules\vm2\package.json (relative path: ./lib)
Field 'browser' doesn't contain a valid alias configuration
Run Code Online (Sandbox Code Playgroud)
尝试了以下简单步骤:
const snowflake = require("snowflake-sdk");
Run Code Online (Sandbox Code Playgroud)
当我运行规范文件时,出现上述错误。
如果我将错误跟踪到文件resolver-compat.js,我可以看到导入失败的地方。
const {AsyncResource} = require('async_hooks');
Run Code Online (Sandbox Code Playgroud)
我已经手动完成了 npm installasync_hooks但也没有运气。
包.json
"devDependencies": {
"cypress": "^11.2.0"
},
"dependencies": {
"async_hooks": "^1.0.0",
"snowflake-sdk": "^1.6.16"
}
Run Code Online (Sandbox Code Playgroud) javascript snowflake-cloud-data-platform cypress async-hooks cypress-task
我读了这篇文章AsyncLocalStorage for Easy Context Passing in Node.js
我尝试在日志中获取 logId,但我不能,因为asyncLocalStorage.getStore()返回未定义。看来 MyLogger 类中的上下文丢失了。怎么解决呢?
这是我的快递应用程序
const asyncLocalStorage = new AsyncLocalStorage();
app.use((req, res, next) => {
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set("requestId", uuid());
next();
});
});
module.exports.asyncLocalStorage = asyncLocalStorage;
Run Code Online (Sandbox Code Playgroud)
这是 MyLogger 类
static log(logId, className, text) {
const { asyncLocalStorage } = require("../server.js");
const store = asyncLocalStorage.getStore()
console.log(this._getBaseStaticLog(logId, logTypes.LOG, text, className));
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试从官方节点 api 文档中运行 Async Hooks 的测试代码,但Error: Cannot find module 'async_hooks'在控制台中出现错误。我已经包含const async_hooks = require('async_hooks');在我的脚本的顶部。这是我的代码:
const async_hooks = require('async_hooks');
// Return the ID of the current execution context.
const eid = async_hooks.executionAsyncId();
// Return the ID of the handle responsible for triggering the callback of the
// current execution scope to call.
const tid = async_hooks.triggerAsyncId();
// Create a new AsyncHook instance. All of these callbacks are optional.
const asyncHook =
async_hooks.createHook({ init, before, after, destroy, promiseResolve }); …Run Code Online (Sandbox Code Playgroud) async-hooks ×6
node.js ×4
javascript ×2
asynchronous ×1
cypress ×1
cypress-task ×1
deno ×1
module ×1
nestjs ×1
rxjs ×1