Node.js使用Mongoose操作MongoDB报连接建立被取消错误
问题根因
报错本质是异步操作时序冲突:Mongoose的所有数据库IO都是异步执行,代码中同时发起find()、updateOne()两个异步数据库请求,find()的回调拿到查询结果后立刻执行mongoose.connection.close()强制断开连接,此时updateOne()还没完成连接建立、执行的全流程,连接被中途销毁就会抛出connection establishment was cancelled异常。
排查修复方案
- 先排查基础环境:确认本地MongoDB服务处于正常运行状态,执行
mongosh命令可以正常连接本地27017端口的Mongo实例,排除服务未启动、端口被占用的基础故障。 - 修正异步逻辑:不要在单个数据库操作的回调里提前关闭连接,等所有数据库操作全部执行完成后再统一关闭连接,参考修正代码如下:
const mongoose = require('mongoose') mongoose.connect("mongodb://localhost:27017/fruitsDB") const fruitsSchema = new mongoose.Schema({ name: { type: String, required: [true, "Why no Name?"] }, rating: { type: Number, min: 1, max: 10 }, review: String }); const Fruit = mongoose.model("Fruit", fruitsSchema); async function runDBTasks() { try { // 按顺序执行查询 const fruits = await Fruit.find(); fruits.forEach(fruit => console.log(fruit.name)); // 查询完成后再执行更新 await Fruit.updateOne({_id:"62b6a681eb136efde7ed17bc"}, {name: "Banana"}); console.log("Successfully updated the document"); } catch (err) { console.log(err); } finally { // 所有操作执行完成(无论成功失败)后统一关闭连接 await mongoose.connection.close(); } } runDBTasks();
- 版本适配提示:如果使用Mongoose 6及以上版本,
connect方法不需要额外传入useNewUrlParser、useUnifiedTopology这类配置参数,默认已经启用,只需要保证连接关闭逻辑在所有异步操作执行完毕后触发即可。
注意:不要把多个Mongoose异步操作平铺在代码顶层,Node.js的事件循环会并发调度这些请求,没有执行顺序保证,很容易出现单操作提前关连导致其他操作失败的问题。
内容的提问来源于stack exchange,提问作者Ayush Parui
相关产品推荐
相关产品推荐

