【问题标题】:Fill array with results from Mongodb find()用 Mongodb find() 的结果填充数组
【发布时间】:2015-03-02 09:20:32
【问题描述】:

在我的 Mongodb 数据库中,我有一组此类文档(Mongoose 描述):

{ colour: String, addedDate: {type: Date} }

例如,这里是一个数据样本:

{colour: 'white', addedDate: '2014-09-24T23:00:00.000Z'}
{colour: 'red', addedDate: '2014-09-24T23:00:00.000Z'}
{colour: 'white', addedDate: '2013-11-24T23:00:00.000Z'}
{colour: 'red', addedDate: '2012-09-24T23:00:00.000Z'}
{colour: 'white', addedDate: '2014-01-24T23:00:00.000Z'}
{colour: 'yellow', addedDate: '2014-09-24T23:00:00.000Z'},

我想获取某些颜色(在数组中指定)、具有最新 ' addedDate' 的文档并将结果存储在数组中。

这是我的代码:

var Colour   = require('../app/models/colour');
var colours = ['white', 'red'];
var results = [];

for (var i = 0; i<colours.length; i++) {
    var name = colours[i];
    (function(output, colour_name) {
        Colour.find({name: colour_name})
            .sort('-addedDate').limit(1).exec(
                function (err, obj) {
                    if (err) return console.log(err);
                    output.push(obj);
                    console.log('output LOG:' + output);
                }
            );
    })(results, name);
}
// Now use the results array
console.log('OUTPUT:' results);

在“输出日志:”中,我得到了应有的数组输出(为简单起见,我没有在这里显示 _id):

output LOG: {colour: 'white', addedDate: '2014-09-24T23:00:00.000Z'} 
output LOG: {colour: 'white', addedDate: '2014-09-24T23:00:00.000Z'}, {colour: 'red', addedDate: '2014-09-24T23:00:00.000Z'}

但是,最终的输出还是空的。

OUTPUT:

如何填写“结果”数组?事实上,我想将它传递给网页,所以我想在渲染页面之前提前收集这些颜色的所有结果。

【问题讨论】:

    标签: javascript arrays node.js mongodb mongoose


    【解决方案1】:

    可能传递给exec 的函数作为其db 操作异步运行,在这种情况下results 数组在您记录它时不会被填充。

    尝试:

    setTimeout(function()
        console.log('OUTPUT:' results);
    }, 1000);
    

    检查是否是这种情况,假设数据库事务最多需要 1000 毫秒。

    注意:这是一个猜测,因为我从未使用过 node/mongo。

    【讨论】:

      【解决方案2】:

      在本节中,

      (函数(输出,颜色名称){

          /* Fetch documents here and send to client from here */
      

      })(结果,名称);

      变量 'results','name' 被传递给函数,由于范围问题,这些值不会在外部更新(即使它们在内部被更改)。

      您可以获取文档并在获取后将这些文档发送给客户端。

      【讨论】:

      • 这可能发生在简单变量上,但对于ArraysObjects,javascript 使用传递引用而不是通常的传递值。
      【解决方案3】:

      Mongoose 调用是异步的。发生的情况是您将每个 Color.find 调用添加到事件队列中,然后在任何 Color.find 调用运行之前调用 console.log('OUTPUT:', results);。这意味着在那个时间点,你的数组是空的。

      解决方案

      传入剩余调用次数和回调。查询完每种颜色后,调用回调。这是fiddle

      var colours = ['white', 'red'];
      var result = {
         items: [],
         left: colours.length
      };
      
      function myCallback(param){
          console.log(param);
      }
      
      for(var i=0; i<colours.length; ++i){
          (function(results, colour_name, cb){
            ...
            setTimeout(function(){ // remove this, just simulating an async call
              // this should be inside the Color.find callback
              result.items.push(colour_name);
              result.left--;
              if (!result.left) {
                cb(result.items);
              }
            },0);
            ...
          }(result, colours[i], myCallback ));
      }
      

      【讨论】:

      • 谢谢!正如其他答案所指出的那样,问题是由于对数据库的异步调用。在其他答案中,这个答案准确地说明了如何解决问题。
      猜你喜欢
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2019-06-05
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多