You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MongoDB find()查询在API路由中返回空值的问题排查

为什么API路由调用MongoDB find()后返回空数据?

我来帮你揪出这个问题的根源,核心问题出在你的findData函数没有正确处理异步操作,导致await根本拿不到查询结果,最终返回给前端的自然是空数据。下面一步步给你拆解:

问题1:findData没有返回Promise

你现在的findData用的是传统的回调函数写法,但整个函数没有返回一个Promise对象。而await只能等待Promise完成,所以当你在路由里写await mongodb.findData(...)时,这个函数默认返回undefineddbResult自然是空的,res.send出去的就是空数据。

问题2:return语句的作用域错了

你在.toArray()的回调里写了return result;,但这个return只是回调函数自己的返回值,和外层的findData函数没关系!外层的findData根本拿不到这个result,相当于白写了这个return。

解决方法:把findData改造成支持Promise/async的写法

下面给你两种可行的修改方案,选一种就行:

方案1:封装成Promise

findData改成返回Promise,用resolve传递结果,reject传递错误:

const findData = (myColl, myDb) => {
  return new Promise((resolve, reject) => {
    MongoClient.connect(url, function(err, client) {
      if (err) {
        reject(err);
        return;
      }
      client
        .db(myDb)
        .collection(myColl)
        .find()
        .sort({ nmFull: 1 })
        .toArray(function(err, result) {
          client.close(); // 无论成功失败都记得关闭连接
          if (err) {
            reject(err);
          } else {
            console.log("find() result...", result);
            resolve(result); // 把查询结果传递出去
          }
        });
    });
  });
};

方案2:用async/await重写(更简洁)

现在MongoClient已经支持Promise了,直接用async/await重写,代码更清晰:

const findData = async (myColl, myDb) => {
  try {
    const client = await MongoClient.connect(url); // 等待连接完成
    const db = client.db(myDb);
    const result = await db.collection(myColl).find().sort({ nmFull: 1 }).toArray();
    console.log("find() result...", result);
    client.close();
    return result; // async函数会自动把结果包装成Promise
  } catch (e) {
    console.log(`findData() error message is...${e.message}`);
    throw e; // 抛出错误让路由里的catch捕获
  }
};

额外检查点

改完之后如果还是没数据,记得确认这几点:

  • MongoDB的连接URLurl配置正确,能正常连接到数据库
  • 数据库名myDb和集合名myColl没有写错(注意大小写敏感)
  • 目标集合里确实有数据(可以在MongoDB Compass里直接查看)

内容的提问来源于stack exchange,提问作者Trewaters

火山引擎 最新活动