NodeJS 有人能解释一下吗:EventEmitter在全局变量

swvgeqrz  于 2023-05-28  发布在  Node.js
关注(0)|答案(1)|浏览(174)

我花了一段时间试图诊断这个错误。
首先,我创建了EventEmitter的子类
文件Client.js

var bindToProcess = function(fct) {
  if (fct && process.domain) {
    return process.domain.bind(fct)
  }
  return fct
};

function Client(){
  EventEmitter.call(this);
}
util.inherits(Client, EventEmitter);

Client.prototype.success =
  function(fct) {
    this.on('success', bindToProcess(fct))
    return this;
}

Client.prototype.login = function(username, password) {
  body = {
    username : username,
    password : password
  };
  var self = this;
  request.post(url, { json:true, body: body }, function (error, response, body) {
      if (error ||response.statusCode != HTTPStatus.OK ) { 
         return self.emit('error', error);
      } 
       return self.emit('success', body);
    });
  return this;
}
module.exports = Client

然后在我的Express应用程序的另一个文件中
文件user.js

var Client = require('../utils/client');
var client = new Client();

// GET '/login'
exports.login = function(req, res){
 client.login(username, password).success( function(user) {
  res.redirect('/');
   }).error( function(error) {
  res.redirect('login');
  });
}

问题是,在第请求时,服务器崩溃并出现错误:

  • 错误:发送后无法设置标题 *

在此期间,我通过在中间件内部创建Client而不是将其作为全局变量来解决这个问题。我只是好奇为什么会这样
谢谢(希望有足够的信息)

llmtgqce

llmtgqce1#

这里发生的是在第二个请求期间从第一个请求调用事件处理函数,因为变量client在请求之间共享。
首先,在全局范围内创建client。然后将两个处理程序附加到它的事件,然后实际执行请求并调用相应的处理程序。
在第二个请求中,将另外两个处理程序附加到同一个对象,然后在成功或失败时通知两个处理程序(来自上一个调用和来自当前调用)。
所以你需要将客户端创建移动到action方法,或者改变代码对事件的响应方式--我可以建议类似promises的方法:将两个回调函数作为参数传递给一个方法;或者只是标准的回调方法:传递错误结果作为回调的第一个参数。

相关问题