在 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.