NodeJS中函数内调用getLastIndice获取MongoDB最大索引失效问题求解
问题原因
你的问题核心是异步调用逻辑处理错误,和你猜测的漏写next()无关:后端路由已经通过res.json()直接返回响应,请求处理已经完成,不需要调用next()(next()仅用于需要将请求传递给后续中间件的场景)。
具体错误点:
fetch是异步API,getLastIndice函数中,你在fetch请求还没返回结果时就直接执行了return语句,此时response变量甚至没有被定义,会直接抛出未定义错误,导致postComparison函数执行中断,后续插入逻辑无法运行。- 你将异步请求当作同步逻辑调用,
getLastIndice()正常情况下也不会返回你需要的最大索引值,只会返回undefined,导致getLastIndice()+1运算失败,中断后续代码。
修复方案
1. 前端getLastIndice函数改造
将函数改为异步函数,用await等待请求返回结果后再返回值:
async function getLastIndice(){ console.log("on appel la fonction get LastIndice"); var requestOptions = { method: 'GET', redirect: 'follow' }; // 等待请求返回结果 const response = await fetch("http://localhost:3000/comparaison/getLastIndice", requestOptions); const lastIndice = await response.json(); console.log('appel de la fonction qui recupere le dernier indice avec comme réponse : ' + lastIndice ); return parseInt(lastIndice); }
2. 前端postComparison函数改造
改为异步函数,等待获取到最大索引后再执行插入逻辑:
async function postComparison(){ console.log("Titre : " + document.getElementById("Titre").value); // 等待获取到最新的索引值 const newId = await getLastIndice() + 1; var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); var raw = JSON.stringify({ "_id": newId, "id_User": "2", "PseudoUser": "bob", "Titre" : document.getElementById("Titre").value }); var requestOptions = { method: 'POST', headers: myHeaders, body: raw, redirect: 'follow' }; fetch("http://localhost:3000/comparaison", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error)); }
3. 后端路由兼容优化(可选)
如果数据库集合为空,现有代码会因为result[0]为undefined报错,建议加空值兼容:
comparaisonRouter.route('/getLastIndice') .get( (req, res) => { var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/"; MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("siteComparaisonMax"); var sort = { _id: -1 }; dbo.collection("comparaisons").find().sort(sort).limit(1).toArray(function(err, result) { if (err) throw err; // 空集合兼容,返回默认初始值0 const lastId = result.length ? result[0]._id : 0; res.json(lastId); db.close(); }); }); })
额外注意
当前的前端生成自增ID的方案存在并发风险:如果两个插入请求同时调用getLastIndice,会拿到同一个ID,插入时会因为_id重复报错。更稳妥的方案是将ID生成逻辑放到后端插入接口中处理,或者直接使用MongoDB默认生成的ObjectId作为_id,不需要自行实现自增ID逻辑。
内容的提问来源于stack exchange,提问作者yhamster
相关产品推荐
相关产品推荐

