Я пытаюсь написать приложение Node.js, которое получает последний добавленный элемент в определенную коллекцию MongoDB, используя драйвер MongoDB Node.js 3.4.Насколько я понимаю, способ сделать это - использовать collection.countDocuments для передачи количества документов в обратный вызов, создать курсор, пропускающий это число - 1, а затем вызвать функцию для фактического возврата документа.Моя проблема в том, что обратный вызов в collection.countDocuments, кажется, никогда не запускается.
Мой код, включая вызовы console.log для отладки:
mongo.connect(dburl, (err, client) => {
console.log("Attempting to connect to database");
if(err) {
console.log("Couldn't connect to server");
throw err;
}
else {
var heatdata;
try {
var db = client.db(dbname);
console.log("Database: " + db.databaseName);
var dbo = db.collection(colName);
console.log("Collection: " + dbo.collectionName);
dbo.countDocuments({}, function(err,count) {
console.log("Count");
if (err) throw err;
dbo.find({}).skip(count - 1).toArray((err, docs) => {
console.log("Made it to skip");
if (err) {
res.writeHead(500, {'Content-Type': 'text/html'});
res.write('<h1>Error on accessing database information.</h1>');
console.log("Couldn't get the requested document");
res.end();
throw err;
}
else {
console.log("Result: " + docs);
heatdata = docs;
console.log("In method: " + heatdata);
}
});
console.log("Past the find");
});
console.log("Past the count");
}
catch(e) {
console.log("Error caught: " + e.name);
throw e.message;
}
console.log("Out of method: " + heatdata);
res.writeHead(200, {'Content-Type': 'application/json'});
res.write(heatdata);
res.end();
}
});
Ожидаемый вывод консоли:
Attempting to connect to database
Database: myDatabase
Collection: myCollection
Count
Made it to skip
Result: {foo:bar}
In method: {foo:bar}
Past the find
Past the count
Out of method: {foo:bar}
Фактический вывод:
Attempting to connect to database
Database: myDatabase
Collection: myCollection
Past the count
Out of method: undefined
TypeError: First argument must be string or Buffer
Другими словами, ни один из кода из dbo.countDocuments не выполняется вообще, включая первый оператор журнала, указывающий, что он вообще вошел в обратный вызов в первую очередь,Что здесь может происходить?
Заранее спасибо.
Редактировать: трассировка выглядит следующим образом:
TypeError: First argument must be a string or Buffer
at write_ (_http_outgoing.js:642:11)
at ServerResponse.write (_http_outgoing.js:617:10)
at mongo.connect (C:\Netshare\heatgraph.js:72:21)
at result (C:\Netshare\node_modules\mongodb\lib\utils.js:414:17)
at executeCallback (C:\Netshare\node_modules\mongodb\lib\utils.js:406:9)
at err (C:\Netshare\node_modules\mongodb\lib\operations\mongo_client_ops.js:286:5)
at connectCallback (C:\Netshare\node_modules\mongodb\lib\operations\mongo_client_ops.js:241:5)
at process.nextTick (C:\Netshare\node_modules\mongodb\lib\operations\mongo_client_ops.js:463:7)
at _combinedTickCallback (internal/process/next_tick.js:132:7)
at process._tickCallback (internal/process/next_tick.js:181:9)
Обратите внимание, что когда я закомментирую countDocuments
заблокируйте и замените его на dbo.find().limit(1).sort({$natural:-1}).next(callback);
, я получаю точно такую же трассировку.
Редактировать 2: Поэтому, когда я запустил исходный код, снятый за пределами прослушивателя http, в котором он находился, он выдал такой вывод консоли:
Attempting to connect to database
Connection: true
Database: faketemps
Collection: temps
Past the count
Out of array method: undefined
Connection: true
Count
Past the find
Made it to skip
Result: [object Object]
In array method: [object Object]
Так что, по сути, причина, по которой обратный вызов, по-видимому, не запускался, заключалась в том, что я не дал ему достаточно времени для фактического запуска.Я постараюсь обернуть все это в setInterval
, чтобы дать ему несколько попыток на самом деле что-то получить, а затем установить тайм-аут в соответствующий момент времени.Несмотря на это, официально извлеченный урок асинхронного программирования.