调用Mongoose操作数据库时如何保证Node.js代码按顺序执行?
问题根因
原生Array.filter()不支持异步回调等待:你传入的async函数会直接返回Pending状态的Promise,filter会将所有Promise判定为真值,直接生成结果数组,不会等待内部await db2.find()执行完成,因此出现执行顺序错乱。
修正方案
先通过Promise.all批量执行所有异步查询逻辑,拿到每一项的过滤判定结果后,再同步对原数组做过滤,就能保证执行顺序符合预期。
修正后完整代码
app.post("/Search", async (req, res) => { // 补充变量声明,避免全局污染 const criteria = req.body.criteria const c = req.body.c const total = req.body.total try { const fquery = await db.find(criteria); console.log(fquery);//print 1 // 第一步:批量执行所有异步查询,拿到每一项的过滤判定结果 const filterResults = await Promise.all( fquery.map(async function (element) { let f = element.field; console.log(f);//print 2 const squery = await db2.find({field:f}); console.log(squery);//print 6 let cond = squery.length == 0;//result set empty let cond2; if (c == value) { cond2 = //some condition } else if (c == value2) { cond2 = //another condition } else { cond2 =//3rd condition } console.log(cond);//print 7 console.log(cond2);//print 8 return (cond || cond2); }) ) // 第二步:同步根据判定结果过滤原数组 let r = fquery.filter((_, index) => filterResults[index]) console.log(fquery);//print 3 console.log("xxxx111");//print 4 console.log(r);//print 5 res.json(r); } catch (err) { res.json({ message: err }); } });
注意事项
如果数据库查询并发量较高,可以把Promise.all替换为串行遍历逻辑,或引入并发限制工具控制请求频率,避免给数据库造成过大压力。
内容的提问来源于stack exchange,提问作者Salma Abuelnaga
相关产品推荐
相关产品推荐

