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が処理された後でイベントを終了してDBを閉じると、ノードインスタンス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 に答える