有人可以解释一下:EventEmitter导致全局变量失败 [英] Can someone explain this : EventEmitter causes failure when global variable

查看:114
本文介绍了有人可以解释一下:EventEmitter导致全局变量失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了一段时间尝试诊断该错误。

I spent a while trying to diagnose this error.

首先,我创建了EventEmitter的子类

First I had created a subclass of 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中的另一个文件中应用

Then in another file in my Express App

文件 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');
  });
}

虽然是在 second 请求中,服务器崩溃并显示错误:

The thing is though on the second request, the server crashes with the error:

错误:发送标头后无法设置标头。

在此期间,我已经通过在中间件内部创建Client而不是使其具有全局变量的方式解决了该问题。我只是很好奇为什么会这样?

In the interim I've solved the problem by created the Client inside the middleware rather than having it a global variable. I'm just curious why this is happening ?

谢谢,
(希望有足够的信息)

Thanks, (hopefully there is enough information)

推荐答案

这里发生的是在第二个请求期间从第一个请求调用事件处理函数,因为共享了变量 client

What happens here is the call of the event handling function from the first request during second request because the variable client is shared between the requests.

首先,在全局范围内创建客户端。然后将两个处理程序附加到其事件,然后实际执行请求并调用相应的处理程序。

At first, the client is created in the global scope. Then two handlers are attached to its events and then the request is actually performed and corresponding handler is called.

在第二个请求上,又有两个处理程序附加到同一对象然后在成功或失败后会通知两个处理程序(从上次调用到当前处理程序)。

On the second request, two more handlers are attached to the same object and then on either success or fail two handlers (from previous call and from the current) are notified.

因此,您需要将客户端创建移至操作方法或进行更改代码如何响应事件-我可以建议类似诺言的方法:将两个回调作为参数传递给一个方法;或只是标准的回调方法:将错误结果作为回调的第一个参数传递。

So you need to move the client creation to the action method or change how the code responds on the events - I can suggest promises-like approach: pass two callbacks as parameters to one method; or just the standard callback approach: pass the error result as first argument of the callback.

这篇关于有人可以解释一下:EventEmitter导致全局变量失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆