NodeJS 程序,执行完后没有自动退出,可能是什么原因造成的?

NodeJS 程序,执行完后没有自动退出,可能是什么原因造成的?

NodeJS 写了一个程序,循环读取一个全局数组变量,当数组不为空时,把条目 POP 下来,提交给处理函数,处理函数使用 Promise 实现。

执行到最后,当数组没有条目了,程序就停止那里不动,没有自动退出。

有遇到过这种情况的吗?这有可能是什么原因造成的?

15 回复

望闻问切,好歹来个代码啊


好大一个项目,我都不知道从哪查起。。。

就想问一下有什么情况会让 NodeJS 不自动退出。。。

process.on(‘uncaughtException’, …)

看看有没有 setInterval

Node.js 中的 io 句柄和 setTimeout/setInterval/setImmediate 默认都会阻止进程退出, 所以你的脚本应该是没跑完, 如果项目太大的话, 可以用 inspect 看一下

有写退出的逻辑吗?当数组为空时是怎么处理的。

如果使用了连接 redis 或者 mysql 的库,一般需要在程序执行完后手动断开连接,否则会保持连接,程序不会退出

使用了 promise 或者 async/wait 这种异步代码是有可能因为某个异常没有捕获,或者资源没有释放而阻塞,用 try/catch/final 处理一下吧。

可能是还有 .on(‘xxx-event’, () => {}) 事件监听没 end 吧

如果还有 task 没有处理完就不会退出
不过一般来讲都是 macrotask 的锅,因为 microtask 从注册到释放不会超过两个 time loop

比如监听端口:
const http = require(‘http’);
const server = http.createServer(console.log);
server.listen(8080);
console.log(Server is running.);

又比如 Promise 预期会执行 resolve 或 reject,只不过暂时还没有执行的时候:
new Promise((res, rej) => {
setTimeout(res, 5000);
})

死循环也会出现进程一直没退出的现象。

process.exit(0);

问题找到了,确实是应为没断开 MySQL 连接造成的。

感谢大家提供的思路。

确实如此,promise 造成了我的代理一直不退出。我这里的 promise 太多,写捕获还是有点麻烦的。看了下 node 有提供–unhandled-rejections=strict 在遇到未捕获时自动退出程序

在Node.js程序中,如果执行完毕后没有自动退出,可能的原因有多种。以下是一些常见的原因及排查方法:

  1. 异步操作未完成: Node.js是事件驱动的,如果程序中有未完成的异步操作(如定时器、文件读写、网络请求等),事件循环会继续运行,导致程序不退出。

    setTimeout(() => {
        console.log('This will delay the exit.');
    }, 10000);
    

    解决方法:确保所有异步操作在程序退出前完成,或者使用process.exit()强制退出(不推荐,除非确实没有其他办法)。

  2. 全局事件监听器: 如果程序中有全局事件监听器(如process.on('exit', ...)),它们可能会阻止程序正常退出。

    process.on('exit', (code) => {
        console.log(`About to exit with code: ${code}`);
    });
    

    解决方法:检查并移除不必要的全局事件监听器。

  3. 未关闭的文件或网络连接: 打开的文件或网络连接未正确关闭,也可能导致程序无法退出。

    const fs = require('fs');
    const file = fs.createReadStream('example.txt');
    // 确保在文件读取完毕后关闭它
    file.on('end', () => {
        file.close();
    });
    

    解决方法:确保所有资源在不再需要时被正确关闭。

总之,要找出Node.js程序不自动退出的原因,通常需要检查异步操作、全局事件监听器和资源关闭情况。

回到顶部