forEach执行含mongoose数据库连接的脚本时仅运行首个文件就停止
问题根因
遍历卡在第一个文件的核心原因是两个执行逻辑的特性冲突:
- 你所用的
shell.exec(shelljs库提供的方法)默认是同步阻塞执行:调用后会一直等待启动的子进程完全退出,才会继续执行后续代码,不会派发完任务就直接进入下一轮循环。 - 子脚本里调用
mongoose.connect建立数据库连接后,会一直维持TCP长连接,Node.js事件循环会因为存在活跃的数据库连接句柄,不会自动退出进程。
两者叠加就会出现你观察到的现象:第一轮循环启动第一个子脚本,子脚本打印数据库连接成功日志后就一直保持运行状态,shell.exec会持续阻塞等待该进程退出,后续的遍历逻辑根本不会触发,自然不会处理剩余文件。
现存逻辑的其他隐患
除了导致遍历中断的核心问题,你的代码还有两个容易触发异常的点:
fs.readdir返回的条目列表不会区分文件和目录,如果group-counter目录下存在普通文件、系统隐藏文件(比如macOS生成的.DS_Store),拼接出来的脚本路径会直接不存在,导致执行报错。- 直接用字符串拼接路径的写法跨平台兼容性差,Windows系统下路径分隔符为
\,直接拼接/会出现路径识别错误,应该统一用path.join方法处理路径拼接。
可行修复方向
根据你的执行需求选对应方案即可:
- 如果需要按顺序逐个执行脚本:在每个子脚本的业务逻辑执行完成后,主动调用
mongoose.disconnect()释放数据库连接,子进程正常退出后,主进程的遍历就会自动进入下一轮。 - 如果需要并行启动所有子脚本:给
shell.exec传入异步配置,改成非阻塞模式,示例:
const scriptPath = path.join('group-counter', file, 'index.js'); shell.exec(`node ${scriptPath}`, { async: true });
设置异步模式后,shell.exec启动子进程后会立刻返回,不会等待子进程退出,遍历会正常走完所有条目。
- 遍历目录时增加条目类型判断,过滤掉非目录的条目,避免无效路径报错。
内容的提问来源于stack exchange,提问作者uyyes
相关产品推荐
相关产品推荐

