Express中await调用MongoJS函数未等待执行返回undefined问题
问题根因
await未按预期等待的核心原因是MongoJS的findOne方法在传入回调函数时,不会返回Promise对象。await关键字仅对Promise类型的返回值生效,当前代码中dbIntro.collection('introducers').findOne(...)因为传入了回调参数,返回值为undefined,因此await拿到结果后会直接执行后续逻辑,不会等待数据库查询完成。
移除回调后抛出CB is not a function错误,是因为当前使用的MongoJS版本默认仅支持回调风格调用,API内部强制要求传入回调参数,没有做无回调时返回Promise的兼容,直接省略回调会触发内部参数校验报错。
修复方案
不要混用回调与await写法,手动将MongoJS的回调风格调用包装为Promise即可,修改后的getIntroducer函数代码如下:
async function getIntroducer(company){ const intro = await new Promise((resolve, reject) => { dbIntro.collection('introducers').findOne({company: company}, function(err, doc) { if (err) { // 查询出错时抛出异常,外层可通过try/catch捕获 return reject(err); } console.log("🚀 ~ file: app.js ~ line 289 ~ intro ~ doc.introducer", doc.introducer) resolve(doc.introducer) }); }); return intro; };
补充注意事项
- 不要在被
await修饰的异步数据库方法中同时传入回调:绝大多数支持双调用模式的数据库驱动,只要检测到参数里传了回调函数,就不会返回Promise对象,直接导致await逻辑完全失效。 - 也可以用Node.js内置的
util.promisify工具把回调风格的findOne转换为Promise版本,减少手动包装Promise的代码量,示例写法:
const { promisify } = require('util'); // 提前绑定方法上下文,转成Promise风格调用 const introFindOne = promisify( dbIntro.collection('introducers').findOne.bind(dbIntro.collection('introducers')) ); async function getIntroducer(company){ const doc = await introFindOne({company: company}); return doc.introducer; }
- 记得在Express路由的异步处理函数中添加
try/catch块捕获数据库查询异常,避免查询报错时触发未捕获异常,导致服务进程意外退出。
内容的提问来源于stack exchange,提问作者CodeTester9001
相关产品推荐
相关产品推荐

