Mongoose save回调未触发但文档已成功存入数据库的问题咨询
Mongoose save回调未触发但文档已成功存入数据库的问题咨询
嘿,我来帮你拆解下这个问题——你遇到的并不是回调真的没触发,而是异步操作的处理逻辑出了问题,咱们一步步理清楚:
核心问题1:异步操作的返回值完全没处理对
你的addArtist函数里,newArtist.save()是个异步操作,但你现在是同步地直接返回值——这意味着addArtist会在save的回调执行前就先返回了,而且回调里的return true/false只是在回调函数内部生效,根本传不到addArtist的返回值里。所以你在/addartist接口里拿到的addedArtist其实一直是undefined,这就导致你误以为回调没触发,但实际上文档已经成功存入数据库了(因为save操作确实在后台执行完成了)。
核心问题2:save回调的参数签名不正确
Mongoose的save()方法回调参数只有两个:(err, doc),你写的(err, data, numAffected)多了一个numAffected参数,这虽然不会导致save失败,但可能会让你对回调的执行结果产生误解。
修复方案
我们需要把addArtist改成异步逻辑,用Promise或者async/await来处理,这样才能正确获取save操作的结果:
方案1:改用async/await(推荐,代码更清晰)
// 把addArtist改成async函数 async function addArtist(aName, aDOB, aBIO) { try { const newArtist = new artists({ artistName: aName, artistDob: aDOB, artistBio: aBIO }); await newArtist.save(); // 等待save操作完成 return true; } catch (err) { console.error('保存失败:', err); return false; } } // 接口里也要用await调用,同时给接口函数加async app.post("/addartist", cors(), async (req, res) => { var artistName = req.body.modalartistname; var artistDOB = req.body.modalartistdob; var artistBio = req.body.modalartistbio; var addedArtist = await addArtist(artistName, artistDOB, artistBio); if (addedArtist) { res.sendStatus(200); } else { console.log("Failure"); res.sendStatus(400); } });
方案2:继续用回调函数(不推荐,代码可读性差)
// 给addArtist加一个回调参数,用来传递结果 function addArtist(aName, aDOB, aBIO, callback) { const newArtist = new artists({ artistName: aName, artistDob: aDOB, artistBio: aBIO }); newArtist.save((err, data) => { // 修正回调参数签名 if (!err) { callback(null, true); } else { callback(err, false); } }); } // 接口里通过回调处理结果 app.post("/addartist", cors(), (req, res) => { var artistName = req.body.modalartistname; var artistDOB = req.body.modalartistdob; var artistBio = req.body.modalartistbio; addArtist(artistName, artistDOB, artistBio, (err, result) => { if (result) { res.sendStatus(200); } else { console.log("Failure:", err); res.sendStatus(400); } }); });
额外小建议
- 给数据库连接加上错误监听,方便排查问题:
conn.on('error', function(err) { console.error("数据库连接失败:", err); });
- Mongoose模型名建议用首字母大写的形式(比如
Artist而非artists),这是行业惯例,避免混淆。 - 你引入的
jquery在Node.js后端环境里没用,可以删掉;前端的jQuery应该在html文件里引入,不需要在后端代码里require。
备注:内容来源于stack exchange,提问作者Gnana Harish
相关产品推荐
相关产品推荐

