【问题标题】:How to wait for the return of a Mongoose search?如何等待 Mongoose 搜索返回?
【发布时间】:2019-08-16 08:47:42
【问题描述】:

我使用 NodeJS / Mongoose 创建了一个 CRUD,以 MVC 样式拆分文件。在下面显示的路由示例中,当执行retrieveOne 例程时,有必要等待其处理,然后将用户重定向到一个或另一个路由。我想使用 Bluebird 等待处理。我需要一些帮助来实施例程。

Index.js ----------------------------- ---

const myCRUD = require('./api/controllers/controller')

router.post('/login', function(req, res, next) {   

   // HOW TO IMPLEMENT BLUEBIRD HERE?

   // How to wait for the "retrieveOne" process and a then do a "if" test (below)?   
   let ret = myCRUD.retrieveOne({ name: "abc test" }); 


   if(!ret) {
      res.redirect('/success')
   } else {
      res.redirect('/error')
   }
})

controller.js ------------------------------------------

const mongoose = require('mongoose');
const Schema = require('./schema-user');
const Model = mongoose.model('users', Schema);

const CRUD = {
   retrieveOne: function(query) {
      Model.findOne(query, function(err, result) {
         if (err) return err;
         return result;
      });
   }
}

module.exports = CRUD;

注意:我已经在 S.O. 中找到了几个使用和不使用 Bluebird 的示例,但我无法让它工作: 示例:12345

【问题讨论】:

  • 顺便说一句,您传递给retrieveOne 的查询看起来有点不稳定。那是错字吗?它应该更像:myCRUD.retrieveOne({ name: "abc test"});
  • 是的,你是对的。这是一个错字。我已经解决了。

标签: javascript node.js mongoose bluebird


【解决方案1】:

您实际上不需要为此使用 Bluebird,因为 mongoose 可以很好地与原生 Promises 配合使用

在您的控制器中:

const mongoose = require('mongoose');
const Schema = require('./schema-user');
const Model = mongoose.model('users', Schema);

const CRUD = {
   retrieveOne: function(query) {
      // findOne() returns a Promise ()
      // https://mongoosejs.com/docs/promises.html
      return Model.findOne(query);
   }
}

module.exports = CRUD;

现在,您可以将路由处理程序设为 async 函数,而只需将 await 设为 Promise

const myCRUD = require('./api/controllers/controller')

router.post('/login', async function(req, res, next) { 
   let ret = await myCRUD.retrieveOne({ name: "abc test"}); 
   if(!ret) {
      res.redirect('/success')
   } else {
      res.redirect('/error')
   }
})

【讨论】:

  • 我是 NodeJS 的新手,我认为我一直在做错事。我复制并粘贴了您的代码,因此出现以下错误:let ret = await myCRUD.retrieveOne(msgJSON); 错误:SyntaxError: await is only valid in async function。你能再帮我一次吗?谢谢!
  • 是的,你必须在函数关键字router.post('/login', async function(req, res, next) {之前添加async
  • 真的......如果你不给我看,我想我永远不会在post 行中看到这个async。现在它起作用了!谢谢。
【解决方案2】:

使用asyncawait

const myCRUD = require('./api/controllers/controller')
const Promise = require('bluebird');

router.post('/login', async function(req, res, next) {   

   // HOW TO IMPLEMENT BLUEBIRD HERE?

   // How to wait for the "retrieveOne" process and a then do a "if" test (below)?   
   let ret = await myCRUD.retrieveOne('{ name: "abc test"'); 


   if(!ret) {
      res.redirect('/success')
   } else {
      res.redirect('/error')
   }
})

// controller.js ------------------------------------------

const mongoose = require('mongoose');
const Schema = require('./schema-user');
const Model = mongoose.model('users', Schema);

const CRUD = {
   retrieveOne: function(query) {
      return new Promise((resolve, reject) => {
        Model.findOne(query, function(err, result) {
           if (err) reject(err);
           resolve(result);
        });
      });
   }
}

module.exports = CRUD;

【讨论】:

  • 虽然这个方法对大部分使用回调的函数都非常有效,但是这里其实没必要,因为Model.findOne返回了一个promise,所以根本不需要使用回调。
  • djheru 响应一样,它还显示以下错误:let ret = await myCRUD.retrieveOne('{ name: "abc test"'); error SyntaxError: await is only valid in async function。我做了一些修改并让它部分工作,但我无法回复resulterr。 :(
  • 如果修改成这种方式就可以了:myCRUD.create(myQuery).then((result) => { console.log(result); }).catch((err) => { console.log(err); })。此外,它必须从函数myCRUD.retrieve 行中删除此let ret = await
猜你喜欢
  • 2019-03-25
  • 2019-03-09
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
  • 2018-09-27
相关资源
最近更新 更多