Node.js调用MongoDB导出函数findAll返回undefined问题求助
解决MongoDB findAll函数返回undefined的问题
嘿,作为Node.js新手遇到这个问题太正常啦!你的findAll函数返回undefined,核心原因是MongoDB的查询是异步操作,你直接在回调里return result根本没法把结果传递到调用它的地方。咱们一步步来修复这个问题:
问题根源分析
在你的crud.js里,dbo.collection(collection).find({}).toArray()是异步执行的——当你调用crud.findAll(...)时,函数会立刻执行完并返回undefined,而toArray的回调要等数据库查询完成后才会触发,这时候回调里的return result根本传不到main.js的test变量里。
解决方案1:使用回调函数(入门级)
这是Node.js早期最常用的异步处理方式,把处理结果的逻辑放到回调函数里,等异步操作完成后再执行:
修改crud.js
exports.findAll = function(db, dbo, collection, callback) { dbo.collection(collection).find({}).toArray(function(err, result) { db.close(); if (err) { // 传递错误给回调 return callback(err); } // 传递结果给回调 callback(null, result); }); };
修改main.js的调用代码
MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("movie"); // 传入回调函数处理结果 crud.findAll(db, dbo, "test", function(err, test) { if (err) throw err; console.log(test); // 这里就能拿到正确的查询结果啦 }); });
解决方案2:使用Promise(更优雅)
回调嵌套多了容易陷入“回调地狱”,用Promise可以让异步代码更清晰:
修改crud.js为Promise版本
exports.findAll = function(db, dbo, collection) { return new Promise((resolve, reject) => { dbo.collection(collection).find({}).toArray(function(err, result) { db.close(); if (err) { // 抛出错误 reject(err); } else { // 返回成功结果 resolve(result); } }); }); };
修改main.js的调用代码
MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("movie"); // 用then处理成功结果,catch处理错误 crud.findAll(db, dbo, "test") .then(test => { console.log(test); }) .catch(err => { throw err; }); });
解决方案3:使用async/await(最简洁)
这是ES6+最推荐的异步处理方式,代码看起来和同步代码一样直观:
crud.js保持Promise版本不变
修改main.js的connect回调为async函数
MongoClient.connect(url, async function(err, db) { if (err) throw err; var dbo = db.db("movie"); try { // 用await等待Promise返回结果 var test = await crud.findAll(db, dbo, "test"); console.log(test); } catch (err) { // 捕获错误 throw err; } });
小提示
另外,关于db.close():如果你的应用之后还要和数据库交互,不要急着关闭连接,建议使用MongoDB的连接池来管理连接,这样性能会更好哦!
内容的提问来源于stack exchange,提问作者Francesco Vicidomini
相关产品推荐
相关产品推荐

