async_hooks 异步钩子
基础
源代码:lib/async_hooks.js
作用:用于追踪异步调用的触发顺序
用法
-
引入
- es6
import async_hooks from 'async_hooks'; - commonjs
const async_hooks = require('async_hooks')
- es6
-
创建异步钩子并启用
- 语法
const hook = async_hooks.createHook({ init(asyncId, type, triggerAsyncId, resource){ const eid = executionAsyncId(); fs.writeSync( 1, `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\n`); }, before(asyncId){}, after(asyncId){}, destroy(asyncId){}, promiseResolve(asyncId){} }).enable()-
三个概念
async scope:异步函数具有的上下文asyncId:上下文在全局中独一无二的id记号(无论反复执行多少遍异步函数,这个id都不变),最外层的 asyncId 是 1triggerAsyncId:当前异步函数是被哪个上下文异步调用的
-
通过追踪asyncId和triggerAsyncId,就能得到异步调用的触发顺序
-
可选五个钩子函数作为创建参数
- 1、
init在异步初始化时 触发 - 2、关于回调函数
before在 回调将要执行前 触发after在 回调执行完 触发- 对于promise异步,二者只会在.then或.catch等链式调用中触发,所以后面谈到的显式resolve里不会触发
- 3、
destory在异步资源销毁时触发(如果存在内存泄漏,依赖垃圾回收,则不会触发) - 4、
promiseResolve在Promise中resovle执行时触发- resolve有两种执行方式
- 显式:在
resolve(结果)时 - 隐式:在
.then(回调)时
- 显式:在
- resolve有两种执行方式
- 1、
-
记得.enable()启用
-
注意:由于打印日志的 console.log 函数也是一个异步调用,如果我们在 钩子函数 中再调用 console.log 那么将再次触发相应的 hook 事件,造成死循环调用,所以要替换成同步打印方式,比如上面用的
fs.writeSync(1,xxx)- 【问】为什么是1
- 【答】在Linux中,一切设备都看作文件。每打开一个文件,就有一个文件描述符。程序启动时默认打开三个I/O设备文件:标准输入文件stdin,标准输出文件stdout,标准错误输出文件stderr,分别得到文件描述符 0, 1, 2
-
启用后的使用
- 语法
- 返回 当前所处异步的asyncId
async_hooks.executionAsyncId() - 返回 当前所处异步的triggerAsyncId
async_hooks.triggerAsyncId()
- 返回 当前所处异步的asyncId
- 语法