2013-11-21 7 views
1

Я пытался разрешить ошибку в приложении nodejs и сузил ее до того, как я реализовал события-эмиттеры. Приложение является приложением express.js, использует классы. Существует некоторый критический аспект NodeJS, который я должен упустить, вокруг использования памяти и жизненных циклов класса/объекта. Я надеялся, что кто-то может указать, почему то, что я делаю, работает не так, как ожидалось.Node.js EventEmitter - происходят плохие вещи

Вот код:

// ServiceWrapper.js: 
var events = require('events'); 

var ServiceClient = function(opts) { 
    this.foobar = ""; 
    this.opts = opts; 
    this.hasFoo = false, this.hasBar = false; 
} 

ServiceClient.prototype = new events.EventEmitter(); 

ServiceClient.prototype.getFoo = function() { 
    var self = this; 
    self.hasFoo = true; 
    self.foobar += "foo"; 
    self.emit('done','foo'); 
} 

ServiceClient.prototype.getBar = function() { 
    var self = this; 
    self.hasBar = true; 
    self.foobar += "bar"; 
    self.emit('done','bar'); 
} 

var ServiceWrapper = function(){} 

ServiceWrapper.prototype.getResponse = function(options, callback) { 
    var servClient = new ServiceClient({}); 
    servClient.on('done', function(what) { 
     if (servClient.hasFoo && servClient.hasBar) { 
      console.log("foo && bar") 
      callback(servClient.foobar); 
     } 
     else { 
      console.log("Don't have everything: " + servClient.foobar); 
     } 
    }); 

    servClient.getFoo(); 
    servClient.getBar(); 
} 

module.exports = ServiceWrapper 

А потом в моей экспресс-приложение:

var ServiceWrapper = require('ServiceWrapper'); 

app.get('/serviceReponse', function(req,res) { 
    var servWrapper = new ServiceWrapper(); 
    servWrapper.getResponse(function(ret) { 
     res.end(ret); 
    }); 
}); 

Поведение на веб-приложение работает, как ожидалось: ответ установлен на «Foobar». Однако, глядя на журналы, похоже, что есть утечка памяти - несколько экземпляров servWrapper. После запуска приложения, то первый запрос генерирует:

Don't have everything: foo 
foo && bar 

Однако, если я обновить страницу, я вижу это:

foo && bar 
Don't have everything: foo 
foo && bar 
foo && bar 

И с каждым обновлением, слушатель обнаруживает несколько «сделали» события - Выходы foo && bar продолжают расти (при условии, что все больше и больше экземпляров ServiceWrapper сохраняются в памяти).

Почему это происходит? (Я ожидаю увидеть результат, который я получаю по первому запросу от каждого запроса).

ответ

2

Благодаря ребятам на # node.js на Freenode для оказания помощи с этим:

уверен, но каждый раз, когда вы приложите слушатель, вы прикрепляя их к тому же излучатель , так как вы не сделали локализовать состояние прототипа в ваш экземпляр, методы прототипа воздействуют на состояние объекта-прототипа. Я считаю, что вы можете это исправить, просто делая EventEmitter.call (это) в конструкторе

Смотрите следующую ссылку для получения дополнительной информации:

Смежные вопросы