Node.js 异步无限循环无报错随机中断运行该如何排查?
问题排查方案
你的循环中断大概率是某一步异步操作陷入了永久pending状态,既不resolve也不reject,导致代码永远走不到finally块,看起来像停止运行,但进程不会崩溃也没有错误日志。可按以下步骤排查:
1. 给所有异步操作加超时兜底,避免永久pending
先实现通用超时工具函数,给所有await的异步操作套上超时逻辑,超时主动抛出错误,就能进入catch块打印日志定位问题:
// 通用超时工具函数 const withTimeout = (promise, timeoutMs, desc = '') => { return Promise.race([ promise, new Promise((_, reject) => { setTimeout(() => { reject(new Error(`操作超时[${desc}],超时时间${timeoutMs}ms`)) }, timeoutMs) }) ]) } // 改进后的循环函数 async function infiniteLoop() { console.log(`[${Date.now()}] 开始新一轮循环`) try { console.log(`[${Date.now()}] 开始请求API`) // 给axios请求额外加超时兜底,避免配置的超时不生效 const response = await withTimeout(axios.get(...), 10000, 'API拉取') console.log(`[${Date.now()}] API请求成功,共${response.data.entities.length}条数据`) console.log(`[${Date.now()}] 开始批量处理数据`) // 给整体数据处理加超时 await withTimeout( Promise.all(response.data.entities.map(async (entity) => { console.log(`[${Date.now()}] 开始处理entity: ${entity.id}`) const product = new Product(entity) // 给单个实体处理加超时 await withTimeout(product.resolve(), 30000, `实体处理${entity.id}`) console.log(`[${Date.now()}] 完成处理entity: ${entity.id}`) })), 120000, '全量数据处理' ) console.log(`[${Date.now()}] 批量处理数据完成`) } catch (e) { console.error(`[${Date.now()}] 循环执行出错:`, e) } finally { console.log(`[${Date.now()}] 进入finally,1s后重启循环`) setTimeout(() => infiniteLoop(), 1000) } } // 全局错误捕获,兜底所有未被catch的错误 process.on('unhandledRejection', (reason, promise) => { console.error(`[${Date.now()}] 未处理的Promise拒绝:`, reason, promise) }) process.on('uncaughtException', (err) => { console.error(`[${Date.now()}] 未捕获的同步异常:`, err) })
2. 排查内部实现的错误吞吃问题
- 检查
Product.resolve()方法的内部实现,有没有内部用try/catch吞掉所有错误、且没有往外抛出也没有打印日志的情况,如果内部异步操作出错被吞,同时后续逻辑停止执行,也会导致Promise永远pending。 - 检查Prisma的配置和使用逻辑:是否配置了查询超时?有没有长事务未提交/回滚的情况?连接池大小是否足够?如果连接池占满没有释放,后续的Prisma查询会一直等待空闲连接,导致逻辑卡住。
3. 监控进程资源状态
- 定期打印进程内存占用:
console.log('内存使用:', process.memoryUsage()),排查是否存在内存泄漏、GC频繁导致进程假死的情况。 - 打印Prisma连接池状态,排查是否连接耗尽导致查询卡住。
4. 挂死时抓取调试信息
如果上述加日志的方式还不能定位,可以用Node.js调试模式运行程序:启动时加--inspect参数,进程卡住时用Chrome开发者工具Attach到进程,查看当前挂起的异步调用栈,直接定位到卡住的代码位置。
内容的提问来源于stack exchange,提问作者zzmichalqq
相关产品推荐
相关产品推荐

