2014-02-06 2 views
1

H есть,Предупреждения от MongoDB - «(узел) предупреждение:.. Рекурсивный process.nextTick обнаружен Это перерыв в следующей версии узла Пожалуйста, используйте setImmediate ...»

Я бег узла 0.10.24 и я стараюсь, чтобы получить все записи из коллекции MongoDB и когда моя коллекция идет более 1000 элементов я получаю эту ошибку:

node.js:375 throw new Error(msg); ^ Error: (node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral. at maxTickWarn (node.js:375:15) at process.nextTick (node.js:480:9) at CursorStream._next (/var/www/html/node_modules/mongodb/lib/mongodb/cursorstream.js:76:11) at 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 at 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)

Я попробовал 2 способа извлечения данных из 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); 
    }); 

}); 
}; 

Что такое правильный способ читать много строк, очень быстро из MongoDB, используя Node.js, не встречая этот вопрос?

спасибо.

UPDATE:

Я нашел еще один способ, который до сих пор не работает, но на этот раз он дает мне это предупреждение после того, как пятисотая возвращаемой строка:

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

И код для этого:

Если я изменяю вызов streamRecords() в stream(), я возвращаюсь к своей первоначальной проблеме в Версии 1. Если я оставлю это таким образом, я получаю только первую 500 строк. : |

ответ

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); 
+0

Hi Neil, я получаю следующую ошибку для res.write (doc); line: http.js: 853 throw new TypeError ('первый аргумент должен быть строкой или буфером'); ^ TypeError: первый аргумент должен быть строкой или буфер в ServerResponse.OutgoingMessage.write (http.js: 853: 11) Я попытаюсь исследовать его и посмотреть, что причиной этого. – asuciu

+0

Я изменил эту строку на: «res.write (JSON.stringify (doc)); "и теперь я снова получаю ту же ошибку: Ошибка: (узел) предупреждение: рекурсивный process.nextTick обнаружен. Кажется, я застрял в этом порочном круге. :( – asuciu

2

После 3-х дней, потянув меня за волосы, я решил просто чистую установку на моем сервере и после установка все последние и самые большие:

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

мой предыдущий драйвер MongoDB для Node.js версии был: 1.1.8, который я думаю, был ответственен за мое горе.

Моя версия 1 работает как очарование!

Смежные вопросы