如何在不对查找索引进行硬编码的情况下使用符号获取节点超时的内部 ID?

How do I get the internal id of a Node Timeout using the symbol without hardcoding a lookup index?

当您在 Node 中创建一个计时器时,您会得到以下对象:

Timeout {
  _called: false,
  _idleTimeout: 500,
  _idlePrev: [TimersList],
  _idleNext: [TimersList],
  _idleStart: 34,
  _onTimeout: [Function],
  _timerArgs: undefined,
  _repeat: null,
  _destroyed: false,
  [Symbol(unrefed)]: false,
  [Symbol(asyncId)]: 5,
  [Symbol(triggerId)]: 1 }

此超时对象的实际数字 ID 包含在 [Symbol(asyncId)] 字段下。我的问题是,我怎样才能以一种非 hackish 的方式获得对该符号的引用?我目前知道的唯一方法是 Object.getOwnPropertySymbols(),但使用硬编码索引似乎很脆弱,因为 f:

$ node -p 't=setTimeout(()=>{}, 500); triggerSym=Object.getOwnPropertySymbols(t)[2];t[asyncId]'
67

有没有更简单的方法可以获取此符号的引用以用于查找?

你完全可以使用Object.getOwnPropertySymbols列出定时器对象的符号,然后迭代找到你想要的那个。在我看来,这非常丑陋,基本上与依赖实现细节或在对象上使用 _foo private-ish 属性 相同。

目前我所知道的 public 符号在 Node 中的主要使用情况是 promisifyable functions,用户可以在其中使用

const promisifySymbol = Symbol.for('nodejs.util.promisify.custom');

Node timer docs没有提到这些符号,所以我建议不要使用这些符号。

如果您确实需要 ID 本身来处理计时器信息的序列化或其他事情,timer [Symbol.toPrimitive]() 实现 returns ID 直接或间接,例如

const timer = setTimeout(() => {}, 0);

console.log(timer[Symbol.toPrimitive]()); // explicit call
console.log(+timer); // implicit call