Node.js 中的异步钩子
使用Async_hooks模块是因为它提供了一个 API 来注册回调,以跟踪在 Node.js 应用程序中创建的异步资源的生命周期。
特征:
- 您可以捕获 Node.js 进程中的任何异步活动。
- 最小的性能开销。
- 强大而灵活的 API。
这些资源在 C++ 中进行跟踪,从 AsyncWrap 类继承的任何内容都是异步资源。
异步资源的生命周期事件:
- init(asyncId, type, triggerAsyncId, resource):当构造一个有可能发出异步事件的类时调用它。
- asyncId:异步资源的唯一 ID。
- type:异步资源的类型。
- triggerAsyncId:异步资源的唯一 ID。
- resource:代表异步操作的资源的引用,需要在destroy时释放。
- 之前(asyncId)和之后(asyncId):
- before在注册用户回调执行之前被调用。
- after在注册用户回调执行后立即调用。
- destroy(asyncId):在asyncId对应的资源被销毁后调用。
function destroy(id) {
print({ stage: 'destroy', id })
}
const hook = asyncHooks.createHook(
{ init, before, after, destroy })
输出:
{id:2, type:'Timeout', triggerAsyncId:3 }
{id:3, type:'TIMEWRAP', triggerAsyncId:3 }
{stage: 'before', id: 4}
{stage: 'before', id:2}
'User callback fired'
{stage: 'after', id: 2}
{stage: 'after', id:3}
{stage: 'destroy', id: 2}
{stage: 'destroy', id:3}
该 API 允许从节点的内置本机模块(如 fs 和 net)监听低级异步资源。
异步 Hooks 高级 API fs.stat、fs.read、fs.open、fs.close 由提供程序表示,然后以对用户更有意义的方式公开,然后组合到更高级别的操作中。基本上,如果我们正在跟踪我们的进程,寻找 CPU 使用率、内存使用率,我们不会每秒都拍摄堆快照,这会杀死我们的服务器。我们来了异步钩子,在服务器运行时我们需要更少的细节,它使操作更快,信息更多。
注意: Node.js 也希望通过 async_hooks 公开未包装的内部计时器,但目前它们太昂贵了。 CLS 用例也不需要这些,但对于一些极端用例,您可能希望观察所有异步活动,甚至包括内部计时器。
可以想象 async_hooks 的一种模式,它也可以使这些内部资源也可观察,并且它是可选的,因为它需要付出代价。