Node.js、Mongo 查找并返回数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35246713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:52:43  来源:igfitidea点击:

Node.js, Mongo find and return data

node.jsmongodb

提问by MM1

I'm new to node and mongo after 15 years of VB6 and MySql. I'm sure this is not what my final program will use but I need to get a basic understanding of how to call a function in another module and get results back.

在使用 VB6 和 MySql 15 年后,我是 node 和 mongo 的新手。我确定这不是我的最终程序将使用的,但我需要对如何调用另一个模块中的函数并返回结果有一个基本的了解。

I want a module to have a function to open a DB, find in a collection and return the results. I may want to add a couple more functions in that module for other collections too. For now I need it as simple as possible, I can add error handlers, etc later. I been on this for days trying different methods, module.exports={… around the function and with out it, .send, return all with no luck. I understand it's async so the program may have passed the display point before the data is there.

我想要一个模块有一个函数来打开一个数据库,在一个集合中查找并返回结果。我可能还想在该模块中为其他集合添加更多功能。现在我需要它尽可能简单,我可以稍后添加错误处理程序等。几天来我一直在尝试不同的方法,module.exports={... 在函数周围,没有它,.send,返回所有没有运气。我知道它是异步的,所以程序可能在数据出现之前已经通过了显示点。

Here's what I've tried with Mongo running a database of db1 with a collection of col1.

这是我尝试使用 Mongo 运行带有 col1 集合的 db1 数据库的方法。

Db1.js
var MongoClient = require('mongodb').MongoClient;
module.exports = {
    FindinCol1 : function funk1(req, res) {
    MongoClient.connect("mongodb://localhost:27017/db1", function (err,db) {
            if (err) {
                return console.dir(err);
            }
            var collection = db.collection('col1');
            collection.find().toArray(function (err, items) {
                    console.log(items);
                   // res.send(items);
                }
            );
        });
    }
};


app.js
a=require('./db1');
b=a.FindinCol1();
console.log(b);

Console.log(items) works when the 'FindinCol1' calls but not console.log(b)(returns 'undefined') so I'm not getting the return or I'm pasted it by the time is returns. I've read dozens of post and watched dozens of videos but I'm still stuck at this point. Any help would be greatly appreciated.

Console.log(items) 在 'FindinCol1' 调用但不是 console.log(b)(returns 'undefined') 时起作用,所以我没有得到回报,或者我在返回时粘贴了它。我已经阅读了数十篇帖子并观看了数十个视频,但我仍然停留在这一点上。任何帮助将不胜感激。

回答by ecoutu

As mentioned in another answer, this code is asynchronous, you can't simply return the value you want down the chain of callbacks (nested functions). You need to expose some interface that lets you signal the calling code once you have the value desired (hence, calling them back, or callback).

正如另一个答案中提到的,这段代码是异步的,你不能简单地在回调链(嵌套函数)中返回你想要的值。您需要公开一些接口,让您在获得所需值后向调用代码发出信号(因此,回调或回调)。

There is a callback example provided in another answer, but there is an alternative option definitely worth exploring: promises.

另一个答案中提供了一个回调示例,但还有一个绝对值得探索的替代选项:promises

Instead of a callback function you call with the desired results, the module returns a promise that can enter two states, fulfilled or rejected. The calling code waits for the promise to enter one of these two states, the appropriate function being called when it does. The module triggers the state change by resolveing or rejecting. Anyways, here is an example using promises:

模块返回一个可以进入两种状态(已完成或已拒绝)的承诺,而不是您使用所需结果调用的回调函数。调用代码等待承诺进入这两种状态之一,当它进入时将调用适当的函数。模块通过resolveing或rejecting触发状态变化。无论如何,这是一个使用承诺的例子:

Db1.js:

db1.js:

// db1.js
var MongoClient = require('mongodb').MongoClient;
/*
node.js has native support for promises in recent versions. 
If you are using an older version there are several libraries available: 
bluebird, rsvp, Q. I'll use rsvp here as I'm familiar with it.
*/
var Promise = require('rsvp').Promise;

module.exports = {
  FindinCol1: function() {
    return new Promise(function(resolve, reject) {
      MongoClient.connect('mongodb://localhost:27017/db1', function(err, db) {
        if (err) {
          reject(err);  
        } else {
          resolve(db);
        }        
      }
    }).then(function(db) {
      return new Promise(function(resolve, reject) {
        var collection = db.collection('col1');
        
        collection.find().toArray(function(err, items) {
          if (err) {
            reject(err);
          } else {
            console.log(items);
            resolve(items);
          }          
        });
      });
    });
  }
};


// app.js
var db = require('./db1');
    
db.FindinCol1().then(function(items) {
  console.info('The promise was fulfilled with items!', items);
}, function(err) {
  console.error('The promise was rejected', err, err.stack);
});

Now, more up to date versions of the node.js mongodb driver have native support for promises, you don't have to do any work to wrap callbacks in promises like above. This is a much better example if you are using an up to date driver:

现在,node.js mongodb 驱动程序的更新版本对promise 提供了本机支持,您无需做任何工作来将回调包装在上面的promise 中。如果您使用的是最新驱动程序,这是一个更好的示例:

// db1.js
var MongoClient = require('mongodb').MongoClient;
                       
module.exports = {
  FindinCol1: function() {
    return MongoClient.connect('mongodb://localhost:27017/db1').then(function(db) {
      var collection = db.collection('col1');
      
      return collection.find().toArray();
    }).then(function(items) {
      console.log(items);
      return items;
    });
  }
};


// app.js
var db = require('./db1');
    
db.FindinCol1().then(function(items) {
  console.info('The promise was fulfilled with items!', items);
}, function(err) {
  console.error('The promise was rejected', err, err.stack);
});

Promises provide an excellent method for asynchronous control flow, I highly recommend spending some time familiarizing yourself with them.

Promise 为异步控制流提供了一种极好的方法,我强烈建议您花一些时间熟悉它们。

回答by Gergo

Yes, this is an async code and with a returnyou will get the MongoClientobject or nothing, based on where you put.

是的,这是一个异步代码,根据您放置的位置,return您将获得MongoClient对象或什么都没有。

You should use a callback parameter:

您应该使用回调参数:

module.exports = {
  FindinCol1 : function funk1(callback) {
    MongoClient.connect("mongodb://localhost:27017/db1", function (err,db) {
      if (err) {
        return console.dir(err);
      }
      var collection = db.collection('col1');
      collection.find().toArray(function (err, items) {
        console.log(items);       
        return callback(items);     
      });
    });
  }
};

Pass a callback function to FindinCol1:

将回调函数传递给FindinCol1

a.FindinCol1(function(items) {
  console.log(items);
});

I suggest you to check this article: https://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks

我建议你查看这篇文章:https: //docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks