You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Promise基于ObjectId查询数据时无法返回结果的问题

问题:Promise查询MongoDB数据成功但无法返回结果

我尝试通过Promise基于ObjectId从数据库中获取数据,数据库已成功查询到数据,但无法返回结果。以下是我的实现代码:

getScreenDetails = function(req, res) { 
  return new Promise((resolve, reject) => { 
    screen.find({ "_id": req.params.id }) 
      .then((response) => { 
        resolve(response); 
      }, (err) => { 
        reject({ status: "failure", error: err }); 
      }) 
  }); 
}; 

解决方案

我来帮你分析几个可能的原因和对应的解决办法:

1. find返回数组而非单个文档,导致后续处理误解

你当前用的screen.find()方法会返回匹配条件的所有文档组成的数组,哪怕只有一条数据。如果你的场景是获取单条详情,建议改用findById或者findOne,这两个方法返回单个文档,更符合业务逻辑:

getScreenDetails = function(req, res) { 
  return new Promise((resolve, reject) => { 
    // 改用findById,自动处理ObjectId转换
    screen.findById(req.params.id) 
      .then((response) => { 
        // 额外判断文档是否存在
        if (!response) {
          return reject({ status: "failure", error: "未找到对应的屏幕数据" });
        }
        resolve(response); 
      })
      .catch((err) => { 
        reject({ status: "failure", error: err.message }); 
      });
  }); 
}; 

2. 未正确处理ObjectId类型匹配

虽然Mongoose通常会自动把字符串类型的_id转换为ObjectId,但某些情况下(比如使用原生MongoDB驱动)可能需要手动转换。如果遇到类型不匹配的问题,可以显式转换:

const { ObjectId } = require('mongoose'); // 先导入ObjectId

getScreenDetails = function(req, res) { 
  return new Promise((resolve, reject) => { 
    screen.find({ "_id": ObjectId(req.params.id) }) 
      .then((response) => { 
        resolve(response); 
      })
      .catch((err) => { 
        reject({ status: "failure", error: err.message }); 
      });
  }); 
}; 

3. 调用Promise时未正确获取结果

你定义了返回Promise的函数,但如果调用时没有用await或者.then()来处理,就无法拿到返回值。比如在路由中应该这样调用:

// 用async/await的方式
app.get('/screens/:id', async (req, res) => {
  try {
    const screenData = await getScreenDetails(req, res);
    res.status(200).json({ status: "success", data: screenData });
  } catch (error) {
    res.status(400).json(error);
  }
});

// 或者用.then().catch()的方式
app.get('/screens/:id', (req, res) => {
  getScreenDetails(req, res)
    .then(screenData => res.status(200).json({ status: "success", data: screenData }))
    .catch(error => res.status(400).json(error));
});

4. 简化Promise写法(可选优化)

因为Mongoose的查询方法本身就返回Promise,你不需要手动包裹一层Promise,可以简化代码,让它更易读:

getScreenDetails = async function(req, res) { 
  try {
    const screenData = await screen.findById(req.params.id);
    if (!screenData) {
      throw new Error("未找到对应的屏幕数据");
    }
    return screenData;
  } catch (err) {
    throw { status: "failure", error: err.message };
  }
}; 

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:00:05