2

在 Node.js 中,我(简要地)有这个脚本:

var http = require('http');
var XmlStream = require('xml-stream');
var mongo = require('mongodb');

var tims = { ... };

var db = new mongo.Db('tims', new mongo.Server("127.0.0.1", 27017, {}), {w: 1});
db.open(function(e, db) {
    var req = http.get({
        host: tims.uri,
        path: '/xml/'+tims.database+tims.services.database
    }).on('response', function(res) {
        res.setEncoding('utf8');
        cProjects = db.collection("projects");
        var xml = new XmlStream(res);

        xml.on('updateElement: Tims ProjectID', function(project) {
            // console.log(project.$text+' - '+project.$.title);
            cProjects.update({project_id: project.$text}, {project_id: project.$text, title: project.$.title}, {upsert:true}, function(err, result) {
                console.log('result: '+result);
            });     
        });

        xml.on('end', function(data) {
            db.close();
        });

    });
});

我正在使用一个名为xml-stream的 Node.js 包,它将来自 Node 的响应块拼凑在一起,以便在处理之前获取有效的 XML。我的问题:如果我遗漏了

xml.on('end', function(data) {
    db.close();
});

我的连接永远不会关闭,控制台只是挂起。好处是console.log('result: '+result);写入控制台,我可以看到我的数据已成功提交。因此,如果我在事件中离开end并在处理完所有 XML 后关闭数据库,则 Node 实例在console.log('result: '+result)写入之前终止。

我是 MongoDB 和 Node.js 的新手,所以我很好奇这里有什么最佳实践来确认,或者简单地指出我做错了什么。

谢谢您的帮助。

4

1 回答 1

1

看起来'end'事件发生在所有update回调完成之前。因此,您需要稍微修改您的代码以跟踪仍待处理的更新数量,并且仅db.close()'end'事件已触发且所有待处理更新都完成后才调用。

所以是这样的:

db.open(function(e, db) {
    var req = http.get({
        host: tims.uri,
        path: '/xml/'+tims.database+tims.services.database
    }).on('response', function(res) {
        res.setEncoding('utf8');
        cProjects = db.collection("projects");
        var xml = new XmlStream(res);
        var end = false;
        var pending = 0;

        xml.on('updateElement: Tims ProjectID', function(project) {
            // console.log(project.$text+' - '+project.$.title);
            ++pending;
            cProjects.update({project_id: project.$text}, {project_id: project.$text, title: project.$.title}, {upsert:true}, function(err, result) {
                console.log('result: '+result);
                if (--pending === 0 && end) {
                    db.close();
                }
            });     
        });

        xml.on('end', function(data) {
            end = true;
        });

    });
});
于 2012-12-19T05:00:26.807 回答