【问题标题】:Storing MongoDB result (Promise pending)存储 MongoDB 结果(承诺待定)
【发布时间】:2019-01-05 08:08:58
【问题描述】:

我一直在尝试将 MongoDB 字段值存储为变量,但我得到了 Promise {< pending >}。我一直以为我知道如何发出异步请求,但似乎我真的不知道。

exports.main = (req, res, next) => {

    const dt = Post.findOne({ active: true }, function(err, data) {

        if (err) throw err;

        return data;

    }).sort({ $natural: -1 }).exec().then(doc => {

        return(doc);

    });

    // Logs --> Promise { <pending> }
    console.log(dt); 

}

【问题讨论】:

    标签: javascript node.js mongodb


    【解决方案1】:

    这是一个类似于this popular one的问题。

    所有依赖查询结果的动作都应该在then内部执行:

    Post.findOne({ active: true }).sort({ $natural: -1 }).exec().then(dt => {
        ...
    });
    

    findOne 回调参数对于 Promise 来说不是必需的。

    async..await 通常可用于类似同步的控制流:

    exports.main = async (req, res, next) => {
        try {
            const dt = await Post.findOne({ active: true }).sort({ $natural: -1 }).exec();
            ...
            next(); // if necessary
        } catch (error) {
            next(error);
        }
    }
    

    正如this answer 中所解释的,由于 Express 不处理承诺,所有错误都应由开发人员通过使用 try..catch 包装整个 async 函数体来处理。

    【讨论】:

      【解决方案2】:

      Mongoose exec() 方法给你一个成熟的承诺,当你在 then 中返回一个值时

      ...exec().then(doc => {
      
          return(doc); // <-- returns a pending promise
      
      });
      

      这会返回一个处于待处理状态的 Promise,就像你当前得到的一样。

      您可以通过多种方式退回文档。使用 async/await,遵循以下模式:

      exports.main = async (req, res, next) => {  
          try {
              const data = await Post.findOne({ active: true }).sort({ $natural: -1 }).exec();
              console.log(data);
      
              res.status(200).send(data);
          } catch(err) {
              console.error(err);
              next();
          }
      }
      

      使用回调函数

      exports.main = (req, res, next) => {
          Post.findOne({ active: true }).sort({ $natural: -1 }).exec((err, data) => {
              if (err) throw err;
              console.log(data);
      
              res.status(200).send(data);
          });
      }
      

      使用承诺

      exports.main = (req, res, next) => {
          Post.findOne({ active: true }).sort({ $natural: -1 }).exec().then(data => {
              console.log(data);
              res.status(200).send(data);
          }).catch(err => {
              console.error(err);
              next();
          });
      }
      

      【讨论】:

        【解决方案3】:

        如果您想访问查询结果,您应该在查询的callback.then 中工作:

        exports.main = (req, res, next) => {
        
            let promise = Post.findOne({ active: true }).sort({ $natural: -1 }).exec();
        
            promise.then((doc) => {
                 console.log(doc);
                 res.send(doc); // send data if needed. I think this is express route handler
            })
            .catch((err) => {
               console.log(err);
               next();
            })
        }
        

        【讨论】:

          猜你喜欢
          • 2019-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-03
          • 2019-10-20
          • 2020-07-13
          • 2020-08-19
          相关资源
          最近更新 更多