【问题标题】:get mongodb data to nodejs array?获取 mongodb 数据到 nodejs 数组?
【发布时间】:2013-09-16 07:26:49
【问题描述】:

我在将 mongodb 数据导入 nodejs 数组时遇到问题,如下所示:

测试数据库:

{
  "supportTicket" : "viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf",
  "msgId" : 1379304604708.0,
  "username" : "Guest-OSsL2R",
  "message" : "hello",
  "_id" : ObjectId("5236849c3651b78416000001")
}

Nodejs:

function _getMsg(st, callback) {
    db.test.find({ supportTicket: st }).toArray(function (err, docs) {
        callback(docs);
    });
}

var nodeArr = _getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (res) {
    console.log(res); // --> res contain data and printed ok
    return res; 
});

console.log('return data: ' + nodeArr )  // --> However, nodeArr  is undefined.

结果如下:

return data: undefined
return data: undefined
[ { supportTicket: 'viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf',
    msgId: 1379304604708,
    username: 'Guest-OSsL2R',
    message: 'dhfksjdhfkj',
    _id: 5236849c3651b78416000001 } ]
[ { supportTicket: 'viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf',
    msgId: 1379304604708,
    username: 'Guest-OSsL2R',
    message: 'dhfksjdhfkj',
    _id: 5236849c3651b78416000001 } ]

问题是:如何从测试数据库中获取数据并将数据分配给nodeArr?

【问题讨论】:

    标签: node.js mongodb callback mongojs


    【解决方案1】:

    如您所见,控制台确实显示了_getMsg 调用的结果。

    _getMsg 不返回值,因此当您尝试将nodeArr 变量分配给结果时,它会得到undefined 的值,因为没有return 值。即使您将其更改为返回值,在调用该函数时,也没有返回结果。

    find 的调用与许多 NodeJ 和 MongoDb 驱动程序一样是异步的。因此,它不会立即返回,这就是为什么您需要回调在函数完成时发出信号的原因。如果没有这种模式,函数调用者将永远不会收到结果。

    您在回调中定义了一个返回值:return res。这会将结果返回给发起调用的函数:callback(docs)。虽然从技术上讲它没有任何问题,但没有理由这样做,因为调用者已经有了结果。这只是忙碌的工作。

    此外,在 NodeJS 的全局范围内声明变量时,我会非常小心。使用异步行为(并且只有一个线程完成所有连接的所有工作),您可能会发现全局变量的值在任何给定时刻都很难在不检查的情况下确定。

    function _getMsg(st, callback) {
        db.test.find({ supportTicket: st }).toArray(function (err, docs) {
            callback(docs);
        });
    }
    
    _getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (res) {
        console.log(res); // --> res contain data and printed ok
        var nodeArr = res;  // just moved the nodeArr declaration to function scope
        // *** do next step here, like send results to client
    });
    

    如果您将结果发送回客户端,在对 _getMsg 的调用中,您可能会遇到类似这样的情况(假设它是在处理 http request 的上下文中):

    response.writeHead(200, { 'Content-Type': 'application/json'});
    response.write(JSON.stringify(nodeArr));
    response.end();
    

    这本可以包含在这样的基本内容中:

    var http = require('http');
    http.createServer(function (req, response) {
        // all requests return the results of calling _getMsg
        // this function won't return until the callback completes
        _getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (nodeArr) {        
            response.write(JSON.stringify(nodeArr));
            response.end();
        });
    }).listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');
    

    【讨论】:

      【解决方案2】:

      你可以这样做:

      var nodeArr;
      function _getMsg(st, callback) {
          db.test.find({ supportTicket: st }).toArray(function (err, docs) {
              callback(docs);
          });
      }
      
      _getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (res) {
          console.log(res); 
          nodeArr = res; 
      });
      
      console.log('return data: ' + nodeArr ) 
      

      但通常这是一个可怕的想法,在您的情况下,console.log 仍会像undefined 一样显示它。这是因为当查询完成时分配将完成,但节点仍将执行代码,直到发生这种情况。

      通常你应该在_getMsg的回调中处理数据并做任何你想做的事情。在大多数情况下,这是安全的工作方式。

      【讨论】:

        【解决方案3】:

        您需要了解异步和同步流之间的概念。

        db.test.find({ supportTicket: st }).toArray(function (err, docs) {
          if (err) throw err;
          nodeArr = docs;
        });
        

        【讨论】:

          【解决方案4】:

          logindata.find({ Name: req.body.username }).select().exec(function (err, data) { })

          【讨论】:

            猜你喜欢
            • 2018-04-13
            • 2016-02-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多