【问题标题】:EventEmiter Fire Once, Request Pends AfterEventEmitter 触发一次,之后请求挂起
【发布时间】:2016-03-28 06:26:46
【问题描述】:

我正在尝试使用 nodejs 在这个平台上创建我的第一个应用程序。在图像上的此代码中,我来自发布请求,我正在尝试检查发送给我的 userData 是否已经注册。如果没有,它将注册用户。为了最小化回调,我将使用事件来告诉我我调用的函数是否已完成。在这种情况下,如果图像右侧的 checkUser 函数属性,如果 db 找到用户,它将发出写在左侧的 userAuthenticated 事件。如果不是,它将写入用户并发出userRegistered 事件。

问题是有时它有效,有时它不。这是我第一次在节点上编写异步函数,我对它的功能感到困惑。

【问题讨论】:

  • 提示:发布代码和错误文本比发布所述项目的屏幕截图要好得多,特别是如果有人想尝试在本地重现问题。

标签: javascript node.js javascript-events event-handling


【解决方案1】:

问题是您在发送响应后没有删除事件处理程序。 on() 保留事件处理程序,直到它们被明确删除。因此,对于每个连接,都会添加新的事件处理程序,但不会删除。

即使您使用 .once() 而不是 .on(),您仍然需要删除未触发的其他事件的处理程序。

恕我直言,您最好只使用单个回调而不是使用 EventEmitter 使事情复杂化。例如:

models/authenticate.js:

// ...

exports.checkUser = function(data, cb) {
  UsersDB.findOne({ fbid: data.id }, function(err, doc) {
    if (err)
      return cb(err);
    if (doc === null)
      insertUser(data, cb);
    else
      cb(null, 'Authenticated', doc);
  });
};
var insertUser = exports.insertUser = function(data, cb) {
  var insertData = {
    fbid: data.id
    first_name: data.first_name
    last_name: data.last_name,
    email: data.email,
    created_at: new Date()
  };
  UsersDB.insert(insertData, function(err, doc) {
    if (err)
      return cb(err);
    cb(null, 'Registered', doc);
  });
};

控制器/authenticate.js:

// ...

model.authenticate(req.body, function(err, action, data) {
  if (err)
    return res.json({ error: err });
  res.json({ action: action, userData: data });
});

此外,您可以简化“检查和插入”逻辑以使用 MongoDB 的“upsert”功能,该功能将为您执行这两个步骤,而不是进行两个单独的数据库调用。要了解如何执行此操作,请查看 this SO answer

【讨论】:

  • 我设法通过使用 res.end() 而不是 res.json() 来解决这个问题,但你的也是一个不错的选择。我也打算把它变成一个承诺。但由于目前代码很简单,它似乎是正确的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-12
  • 2014-04-15
  • 1970-01-01
  • 2014-02-08
  • 2013-06-02
  • 1970-01-01
相关资源
最近更新 更多