在NodeJS中运行以下代码时,我收到错误 MongoError:应用程序已关闭连接。我试图解决它但无法一直无法解决。我需要别人的帮助......
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
if(err) throw err;
var data = db.collection('data');
var options = { 'sort' : [['State', 1], ['Temperature', -1]] };
var cursor = data.find({}, {}, options);
var firstState = '';
var currentState='';
var previousState='';
var previousRecord='';
cursor.each(function(err, doc) {
if(err) throw err;
if(doc == null) {
return db.close();
}
currentState= doc['State'];
previousState = previousRecord['State'];
if(previousState === undefined) {
console.dir(currentState);
firstState= doc['State'];
db.collection('data').update({'_id' : doc['_id']}, {$set :{'month_high' : true}}, {'upsert' : true}, function(err, upserted){
if(err) throw err;
console.dir("Successfully upserted "+upserted + " document!");
});
} else if(currentState !=previousState){
if (firstState!=currentState){
console.dir(previousState);
db.collection('data').update({'_id' : previousRecord['_id']}, {$set :{'month_high' : true}}, {'upsert' : true}, function(err, upserted){
if(err) throw err;
console.dir("Successfully upserted "+upserted + " document!");
});
}
}
previousRecord = doc;
});
});
答案 0 :(得分:1)
这是异步调用数据库的异步代码,但此处使用的[root@mongo wok]# cd node_modules/
[root@mongo node_modules]# ls
socket.io
[root@mongo node_modules]# cd socket.io/
[root@mongo socket.io]# ls
History.md index.js lib LICENSE Makefile node_modules package.json Readme.md
[root@mongo socket.io]# ls -al
total 68
drwxr-xr-x 4 root root 4096 Aug 15 01:50 .
drwxr-xr-x 3 root root 4096 Aug 15 01:50 ..
-rw-r--r-- 1 root root 15740 Jul 14 17:36 History.md
-rw-r--r-- 1 root root 36 Jul 8 09:29 index.js
drwxr-xr-x 2 root root 4096 Aug 15 01:50 lib
-rw-r--r-- 1 root root 1096 May 25 14:29 LICENSE
-rw-r--r-- 1 root root 235 May 25 14:29 Makefile
drwxr-xr-x 8 root root 4096 Aug 15 01:50 node_modules
-rw-r--r-- 1 root root 33 May 25 14:29 .npmignore
-rw-r--r-- 1 root root 1932 Aug 15 01:50 package.json
-rw-r--r-- 1 root root 10380 Jul 8 09:29 Readme.md
-rw-r--r-- 1 root root 197 Jul 8 09:29 .travis.yml
[root@mongo socket.io]# cat package.json
{
"name": "socket.io",
"version": "1.3.6",
"description": "node.js realtime framework server",
"keywords": [
"realtime",
"framework",
"websocket",
"tcp",
"events",
"socket",
"io"
],
"repository": {
"type": "git",
"url": "git://github.com/Automattic/socket.io.git"
},
"scripts": {
"test": "mocha --reporter dot --slow 200ms --bail"
},
迭代器不会等待包含的回调完成。
这是此处出错的主要原因,因为在调用.each()
时处理尚未实际完成。所以这就是需要解决的问题。
虽然对代码的一般清理肯定是有序的,但这里的主要内容是用stream processing替换该循环,并且通过仅改变条件避免“重复自己”调用“更新”并将流量控制保持在一个地方:
db.close()
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
if(err) throw err;
var data = db.collection('data');
var options = { 'sort' : [['State', 1], ['Temperature', -1]] };
var cursor = data.find({}, {}, options);
var firstState = '',
currentState='',
previousState='',
previousRecord='';
cursor.on("end",function() {
db.close();
});
cursor.on("err",function(err) {
throw err;
});
cursor.on("data",function(data){
cursor.pause(); // Stops events emitting on stream
currentState = doc.State;
previousState = previousRecord.State;
var query = { "_id": null };
if (previousState === undefined) {
console.dir(currentState);
firstState= doc.State;
query._id = doc._id;
} else if(currentState != previousState) {
if (firstState != currentState) {
console.dir(previousState);
query._id = previousRecord._id;
}
}
if (query._id != null) {
db.collection('data').update(
query,
{ "$set":{ "month_high": true } },
{ "upsert": true },
function(err, upserted){
if(err) throw err;
console.dir("Successfully upserted "+upserted + " document!");
cursor.resume(); // resumes events on stream
previousRecord = doc;
});
} else {
cursor.resume(); // resumes events on stream
previousRecord = doc;
}
});
});
和.pause()
方法确保在检索当前文档的当前处理完成之前,流中不会发出新数据。这样可以检查外部变量。
请注意,.resume()
也会在.resume()
的回调中“调用”,因为您不想继续此操作,直到返回完成为止。
答案 1 :(得分:0)
我重写了实施 node stream 界面的应用程序,该界面最终解决了" MongoError:连接已被应用程序关闭" 的问题。
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
if(err) throw err;
var data = db.collection('data');
var options = { 'sort' : [['State', 1], ['Temperature', -1]] };
var cursor = data.find({}, {}, options);
var previousState='';
cursor.on("end", function(){
db.close();
});
cursor.on("err", function(){
console.dir("Error on:" + err);
throw err;
});
cursor.on("data", function(doc){
cursor.pause();
if(previousState != doc.State){
previousState = doc.State;
var query = { _id: doc._id};
var operator = {$set: {month_high: true}};
db.collection('data').update(query, operator, {'upsert' : true}, function(err, upserted){
if(err){
console.dir('Error : '+ err);
throw err;
}
console.dir("Successfully upserted "+ upserted + " document!");
cursor.resume();
});
} else{
cursor.resume();
}
});
});