0

node-mongodb-native と EventEmitter の間で奇妙な問題が発生しています。

問題を次のコードに減らしました。

var mongodb = require( 'mongodb' ),
    Server = mongodb.Server,
    Db = mongodb.Db,
    events = require( 'events' ).EventEmitter.prototype;

// Create a mongo client object
var client = new Db( 'tartempion',
    new Server(
        '127.0.0.1',
        27017
    )
);

// Open the connection
client.open( function( err, db ) {
    if ( err ) throw err;
    database = db;
    console.log( 'Database driver loaded.' );
    events.emit( 'hi' );
});

// If I comment this out, I don't get the error anymore
// and the "Database driver loaded." log is displayed.
events.on( 'hi', function() {
    console.log( 'hey man' );
});

そして、私はこのエラーが発生しています:

net.js:140
    // Uncomment the following lines after libuv backend is stable and API
      ^
RangeError: Maximum call stack size exceeded

これはコールバックのイベントに関連している可能性があると思いましたが、このコードは機能します:

events.on( 'hi', function() {
    console.log( 'hey man' );
});

f( function() {
    events.emit( 'hi' );
});

function f( callback ) {
    callback();
}

だから...問題がどこにあるのかわかりません。

参考までに、これを node-mongodb-native issue queueに相互投稿しま​​した。

4

2 に答える 2

3

あなたが言うなら:

events = require( 'events' ).EventEmitter.prototype;
event.on('foo');

すべてのイベントオブジェクトがこのバインディングを取得するため、トラブルを求めています(すべてのイベントの基本プロトタイプに書き込んでいるため)...

イベントをバインドする新しいオブジェクトをインスタンス化する方がはるかに優れています(ジョナソンが言うように)...

sharedEventEmitter.js

var events = require('events');
var eventEmitter = new events.EventEmitter();
module.exports = eventEmitter;

プロジェクトの残りの部分から、これをシングルトンのように扱うことができます。これは、リッスンしているすべてのものにイベントを発行する 1 つのオブジェクトです。require('sharedEventEmitter') するたびに、同じインスタンスが返されます (シングルトンです)。

a.js

var sharedEvents = require('./sharedEventEmitter');
sharedEvents.on('foo', function(st){
  console.log(st);
})

b.js

var sharedEvents = require('./sharedEventEmitter');
sharedEvents.emit('hello from another file');
于 2012-08-16T19:24:57.867 に答える
2

オブジェクトへの単なる参照ではなくevents、インスタンスとして定義する必要があります。EventEmitterEventEmitter.prototype

var ...,
    EventEmitter = require('events').EventEmitter,
    events = new EventEmitter;

またはから継承するオブジェクトとしてEventEmitter.prototype

var ...,
    events = Object.create(require('events').EventEmitter.prototype);

EventEmitter.prototypeの実行ご​​とに 1 つしか取得できないためnode.exe( の結果require('events')がキャッシュされるため)、これをインスタンスとして使用すると、コア Node API 全体で、および のようなサードパーティ モジュールによって使用されるすべての実際のインスタンスが変更される可能性がありますmongodb


Brandon が提案したように、2 つのモジュールでインスタンスにアクセスする必要がある場合は、3 番目のモジュールで定義します。

// emitter.js
var EventEmitter = require('events').EventEmitter;
module.exports = new EventEmitter;
var ...,
    events = require('./emitter');
于 2012-08-16T18:39:04.733 に答える