You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js应用中如何通用检测运行中Promise或进程并实现查询端点?

检查Node.js应用中运行状态的Promise

Node.js本身并没有提供直接获取所有活跃Promise的原生API,但可以通过两种通用方式实现,无需逐个修改业务代码来跟踪进程状态:

方法一:猴子补丁(Monkey Patch)Promise

通过重写Promise的构造函数和静态方法,自动跟踪所有创建的Promise,维护一个活跃Promise集合:

// 在应用启动最开始执行这段代码
const activePromises = new Set();
const OriginalPromise = Promise;

// 重写Promise构造函数
Promise = function(...args) {
  const promise = new OriginalPromise(...args);
  activePromises.add(promise);
  
  // Promise完成或拒绝后从集合移除
  promise.finally(() => activePromises.delete(promise));
  
  return promise;
};

// 处理Promise.resolve静态方法
Promise.resolve = function(value) {
  const promise = OriginalPromise.resolve(value);
  if (promise instanceof OriginalPromise) {
    activePromises.add(promise);
    promise.finally(() => activePromises.delete(promise));
  }
  return promise;
};

// 处理Promise.reject静态方法
Promise.reject = function(reason) {
  const promise = OriginalPromise.reject(reason);
  if (promise instanceof OriginalPromise) {
    activePromises.add(promise);
    promise.finally(() => activePromises.delete(promise));
  }
  return promise;
};

之后在/getRunningProcess端点中,直接读取活跃Promise的状态:

router.get('/getRunningProcess', (req, res) => {
  res.status(200).json({ 
    activePromisesCount: activePromises.size,
    hasRunningProcesses: activePromises.size > 0
  });
});

注意事项:

  • 猴子补丁可能与第三方库的Promise实现冲突,若应用中使用了非原生Promise(如Bluebird),需要针对性调整。
  • 所有Promise(包括Node.js内部产生的)都会被跟踪,若需要过滤业务相关的Promise,可以在创建时添加标识区分。

方法二:使用Node.js async_hooks模块

利用Node.js底层的async_hooks模块跟踪异步资源,精准捕获Promise类型的异步操作:

const async_hooks = require('async_hooks');

const activePromises = new Set();
const asyncIdToResource = new Map();

// 创建异步钩子
const hook = async_hooks.createHook({
  init(asyncId, type, triggerAsyncId, resource) {
    // 仅跟踪Promise类型的异步资源
    if (type === 'PROMISE') {
      asyncIdToResource.set(asyncId, resource);
      activePromises.add(resource);
    }
  },
  destroy(asyncId) {
    // 异步资源销毁时移除记录
    const resource = asyncIdToResource.get(asyncId);
    if (resource) {
      activePromises.delete(resource);
      asyncIdToResource.delete(asyncId);
    }
  }
});

// 启用钩子
hook.enable();

对应的端点实现:

router.get('/getRunningProcess', (req, res) => {
  res.status(200).json({ 
    activePromisesCount: activePromises.size,
    hasRunningProcesses: activePromises.size > 0
  });
});

注意事项:

  • async_hooks是底层API,不同Node.js版本可能存在行为差异,需要测试兼容性。
  • destroy事件的触发依赖垃圾回收,可能存在延迟,导致统计结果有短暂偏差。
  • 该方法会带来一定性能开销,高并发场景下需要评估影响。

内容的提问来源于stack exchange,提问作者Dense04

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:07:18