来自mongodb的警告 - “(节点)警告:已检测到递归process.nextTick。这将在下一版本的节点中中断。请使用setImmediate ...”

时间:2014-02-06 00:13:56

标签: node.js node-mongodb-native

那里,

我正在运行节点0.10.24并且我正在尝试从mongodb集合中获取所有记录,一旦我的集合超过1000个元素,我就会收到此错误:

  

的node.js:375           抛出新错误(msg);                 ^   错误:(节点)警告:检测到递归process.nextTick。这将在下一版本的节点中中断。请使用setImmediate进行递归递延。       在maxTickWarn(node.js:375:15)       at process.nextTick(node.js:480:9)       在CursorStream._next(/var/www/html/node_modules/mongodb/lib/mongodb/cursorstream.js:76:11)       在CursorStream._onNextObject(/var/www/html/node_modules/mongodb/lib/mongodb/cursorstream.js:98:8)       at /var/www/html/node_modules/mongodb/lib/mongodb/cursorstream.js:78:12       在Cursor.nextObject(/var/www/html/node_modules/mongodb/lib/mongodb/cursor.js:540:5)       at /var/www/html/node_modules/mongodb/lib/mongodb/cursorstream.js:77:18       at process._tickCallback(node.js:415:13)

我尝试了两种从mongodb获取数据的方法,但没有成功。

版本1:

exports.findAll = function(req, res) {
db.collection('products', function(err, collection) {
    var first = true;

    var stream = collection.find().batchSize(10000).stream();
    var results = [];

    stream.on('data', function(item){
        results.push(item);
    }).on('error', function (err) {
        // handle the error
        console.log(err);
    }).on('close', function () {
        // the stream is closed, so complete the response with res.end();
        res.send(results);
    });
});
};

第2版:

var sys = require('sys'),
http = require('http'),
mongodb = require('mongodb');

var server = new mongodb.Server("localhost", 27017, {});
var db = new mongodb.Db('productdb', server, {});
var client  = null

db.open(function (error, clientParam) {
    if (error) {
            db.close();
            throw error;
    }
    client = clientParam;
});

http.createServer(function(req, res) {
    var collection = new mongodb.Collection(client, 'products');

    collection.find({}, {}, function(err, cursor) {
            if(err == null){
             cursor.toArray(function(err, docs){
                     res.writeHead(200, {'Content-Type': 'application/json'});
                     res.write(docs);
                     res.end();
                     //console.log(docs);
             });
            }else{
                    res.writeHead(200, {'Content-Type': 'text/html'});
                res.write('An error occurred!');
                res.end();
                throw err;
            }
    });
    }).listen(8088);

在版本3中,当我添加一个流暂停并且在超时后我恢复它,我将得到我想要的结果,但是有明显的延迟。

第3版:

exports.findAll = function(req, res) {
db.collection('products', function(err, collection) {
    var first = true;

    var stream = collection.find().batchSize(10000).stream();
    var results = [];

    stream.on('data', function(item){
        results.push(item);
        stream.pause();

        setTimeout(function(){
            stream.resume();
        }, 1);
    }).on('error', function (err) {
        // handle the error
        console.log(err);
    }).on('close', function () {
        // the stream is closed, so complete the response with res.end();
        res.send(results);
    });

});
};

使用node.js从mongodb读取大量行的正确方法是什么,没有遇到这个问题?

谢谢。

更新:

我找到了另一种方法仍然不起作用,但这次它在第500行返回后给了我这个警告:

[WARNING] streamRecords method is deprecated, please use stream method which is much faster

这个代码是:

db.collection('products', function(err, collection) {

    var stream = collection.find().streamRecords();
    var results = [];

    stream.on('data', function(item){
        results.push(item);
    }).on('error', function (err) {
        // handle the error
        console.log(err);
    }).on('end', function () {
        // the stream is closed, so complete the response with res.end();
        res.send(results);
    });
});

如果我将streamRecords()调用更改为stream(),我将回到版本1中的初始问题。如果我这样离开,我只会获得前500行。 :|

2 个答案:

答案 0 :(得分:2)

拔了头三天后,我决定在我的服务器上安装一个干净的安装程序,然后安装所有最新的和最好的:

    "express": "3.x",
    "mongodb": "1.3.23",
    "connect-timeout": "0.0.1"
    "npm": "1.x"

我以前用于node.js版本的mongodb驱动程序是:1.1.8,我认为这是导致我悲伤的原因。

我的版本1就像一个魅力!

答案 1 :(得分:1)

只是想知道是否使用光标上的每个发生了同样的问题。因此,只需对代码进行一些轻微编辑(显然更改序列化位,但只显示放置位置):

http.createServer(function(req, res) {
var collection = new mongodb.Collection(client, 'products');

collection.find({}, {}, function(err, cursor) {
    if(err == null){
        res.writeHead(200, {'Content-Type': 'application/json'});

        cursor.each(function(err, doc){
            if (doc != null) {
                res.write(doc);
            }
        });

        res.end();
        //console.log(docs);

     }else{
         res.writeHead(200, {'Content-Type': 'text/html'});
         res.write('An error occurred!');
         res.end();
        throw err;
     }
});
}).listen(8088);