代码之家  ›  专栏  ›  技术社区  ›  Đức Nguyễn

将mongodb数据获取到nodejs数组?

  •  5
  • Đức Nguyễn  · 技术社区  · 12 年前

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

    测试数据库:

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

    节点js:

    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?

    4 回复  |  直到 12 年前
        1
  •  5
  •   WiredPrairie    12 年前

    正如您所注意到的,控制台确实显示了 _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
    });
    

    如果您将结果发送回客户端,则在对 _获取消息 您可能会遇到这样的情况(假设它是在处理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
  •  5
  •   durum    12 年前

    您可以这样做:

    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
  •  1
  •   moka    12 年前

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

    db.test.find({ supportTicket: st }).toArray(function (err, docs) {
      if (err) throw err;
      nodeArr = docs;
    });
    
        4
  •  0
  •   Gunjan Kumar    6 年前

    logindata.find({Name:req.body.username}).select().exec(函数(错误,数据){ })