我如何跟踪 NodeJS 应用程序中未实现的承诺的数量?

How can I track the number of unfulfilled promises in a NodeJS application?

我经常在 NodeJS 和 JavaScript 中使用一种模式,在这种模式中,我使用 Promise.race 将超时与另一个承诺结合起来,就像这样...

let timer
let p1 = x => {
  return new Promise((resolve, reject) => {
    bSomeFunctionCall(x) ? resolve() : reject()
  }).finally(() => { console.log('p1 done') })
}
let p2 = ms => {
  return new Promise((resolve, reject) => {
    timer = setTimeout(() => {
      reject('timeout')
    }, ms)
  }).finally(() => { console.log('timeout done') })
}
let p3 = Promise.race([p1(v1), p2(3000)])
await p3.finally(() => {
  console.log('race done')
  clearTimeout(timer)
  console.log('done')
})

编辑:打字错误,'timer' 是清除范围内的变量。

但是,我从来没有看到 p2.finally() 消息,除非它超时并拒绝,这让我想知道是否每次我使用这种模式时我都会创建一个未实现的承诺漂浮在那里......可能成千上万。

我想知道 p3 中的 clearTimeout() 是否会导致 promise 解析,并且由于 resolve() 未定义,它只是悄悄地解决,但我不应该看到 p2 的 finally() 调用吗?

我不明白p2是如何解决而不调用它的finally()方法的。

我如何调试它以说服自己我没有在后台搞得一团糟?我希望有一种方法可以在调试模式下检查未完成的承诺数量...

.finally(() => { console.log('timeout done') }) 总是被调用,除非你从来没有 reject Promise,这发生是因为你在 Promise.race 解决时显然正在清除超时。

在您的代码中,您将超时 ID 分配给 timer,然后使用 timeout 变量发出 clearTimeout,该脚本中未定义该变量。所以我假设你正在清除 p2 承诺超时,并且由于 p1 首先完成,当你清除计时器时 p2 永远不会得到解决。

所以不要使用 clearTimeout,因为如果您使用 Promise.race 就没有意义,并且 finally 将始终在 p2


仅用于调试目的,您可以覆盖Promise构造函数以跟踪所有承诺。

Promise = class extends Promise {
    static list = []
    constructor(...args) {
        let p = super(...args)
        Promise.list.push(p)
        return p;
    }
};

// Promise.list (will contain all promises, filter by `pending`

您也可以查看这个答案: