EventEmitter 触发一次,之后请求挂起
EventEmiter Fire Once, Request Pends After
我正在用 express 尝试在 nodejs 上尝试在这个平台上制作我的第一个应用程序。在图像上的这段代码中,我来自 post 请求,我正在尝试检查发送给我的 userData 是否已经注册。如果不是,它将注册用户。为了最小化回调,我将使用事件来告诉我调用的函数是否完成。在这种情况下,如果图像右侧的 checkUser 函数 属性,如果 db 找到了用户,它将发出左侧写的 userAuthenticated
事件。如果不是,它将写入用户并发出 userRegistered
事件。
问题是有时有效,有时无效。这是我第一次在节点上编写异步函数,我对它的功能感到困惑。
- 代码 - http://prntscr.com/9h2qr2
- 浏览器错误 - http://prntscr.com/9h2szw
- 节点错误 - http://prntscr.com/9h2t81
问题是您没有在发送响应后删除事件处理程序。 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);
});
};
controllers/authenticate.js:
// ...
model.authenticate(req.body, function(err, action, data) {
if (err)
return res.json({ error: err });
res.json({ action: action, userData: data });
});
此外,您可以简化 "check and insert" 逻辑以使用 MongoDB 的 "upsert" 功能,该功能将为您执行这两个步骤,而不是进行两个单独的数据库调用。要了解如何执行此操作,请查看 this SO answer.
我正在用 express 尝试在 nodejs 上尝试在这个平台上制作我的第一个应用程序。在图像上的这段代码中,我来自 post 请求,我正在尝试检查发送给我的 userData 是否已经注册。如果不是,它将注册用户。为了最小化回调,我将使用事件来告诉我调用的函数是否完成。在这种情况下,如果图像右侧的 checkUser 函数 属性,如果 db 找到了用户,它将发出左侧写的 userAuthenticated
事件。如果不是,它将写入用户并发出 userRegistered
事件。
问题是有时有效,有时无效。这是我第一次在节点上编写异步函数,我对它的功能感到困惑。
- 代码 - http://prntscr.com/9h2qr2
- 浏览器错误 - http://prntscr.com/9h2szw
- 节点错误 - http://prntscr.com/9h2t81
问题是您没有在发送响应后删除事件处理程序。 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);
});
};
controllers/authenticate.js:
// ...
model.authenticate(req.body, function(err, action, data) {
if (err)
return res.json({ error: err });
res.json({ action: action, userData: data });
});
此外,您可以简化 "check and insert" 逻辑以使用 MongoDB 的 "upsert" 功能,该功能将为您执行这两个步骤,而不是进行两个单独的数据库调用。要了解如何执行此操作,请查看 this SO answer.