在 AsyncHook 回调中打印
因为打印到控制台是异步的操作,所以 console.log()
会导致 AsyncHook
回调被调用。
在 AsyncHook
回调函数中使用 console.log()
或类似的异步操作将导致无限递归。
当调试时,一个简单的解决方案是使用同步的日志记录操作,例如 fs.writeFileSync(file, msg, flag)
。
这将打印到文件并且不会递归地调用 AsyncHook
,因为它是同步的。
import { writeFileSync } from 'node:fs';
import { format } from 'node:util';
function debug(...args) {
// 在 AsyncHook 回调中调试时使用这样的函数
writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' });
}
const fs = require('node:fs');
const util = require('node:util');
function debug(...args) {
// 在 AsyncHook 回调中调试时使用这样的函数
fs.writeFileSync('log.out', `${util.format(...args)}\n`, { flag: 'a' });
}
如果日志记录需要异步的操作,则可以使用 AsyncHook
本身提供的信息来跟踪导致异步操作的原因。
当日志本身导致调用 AsyncHook
回调时,应跳过日志记录。
通过这样做,否则无限递归被打破。
Because printing to the console is an asynchronous operation, console.log()
will cause AsyncHook
callbacks to be called. Using console.log()
or
similar asynchronous operations inside an AsyncHook
callback function will
cause an infinite recursion. An easy solution to this when debugging is to use a
synchronous logging operation such as fs.writeFileSync(file, msg, flag)
.
This will print to the file and will not invoke AsyncHook
recursively because
it is synchronous.
import { writeFileSync } from 'node:fs';
import { format } from 'node:util';
function debug(...args) {
// Use a function like this one when debugging inside an AsyncHook callback
writeFileSync('log.out', `${format(...args)}\n`, { flag: 'a' });
}
const fs = require('node:fs');
const util = require('node:util');
function debug(...args) {
// Use a function like this one when debugging inside an AsyncHook callback
fs.writeFileSync('log.out', `${util.format(...args)}\n`, { flag: 'a' });
}
If an asynchronous operation is needed for logging, it is possible to keep
track of what caused the asynchronous operation using the information
provided by AsyncHook
itself. The logging should then be skipped when
it was the logging itself that caused the AsyncHook
callback to be called. By
doing this, the otherwise infinite recursion is broken.