EventEmiter消防一次,请求过后

时间:2015-12-22 04:01:28

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

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

问题在于它有时会起作用,有时却不起作用。这是我第一次在节点上编写异步函数,我对它的运行方式感到困惑。

1 个答案:

答案 0 :(得分:1)

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

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

恕我直言,你最好只使用一个回调而不是使用EventEmitter使事情变得复杂。例如:

<强>模型/ 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 });
});

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