gpt4 book ai didi

redis - 试图理解一篇关于 socket.io 和 redis 的文章的代码片段

转载 作者:可可西里 更新时间:2023-11-01 11:17:06 24 4
gpt4 key购买 nike

我正在尝试理解一篇文章 here ,现在一切都清楚了,除了一个代码片段,在前一个代码块中提到,总共 1 到 17 行,这个片段是从第 1 到第 9 行:

app.use(function(req,res,next) {
redis.get(req.user.email, function(err, id) {
if (err) next(err);
req.emitToUser = function() {
var soc = id && io.to(id);
soc.emit.apply(soc, arguments);
}
});
});

我认为我的 javascript 知识中的一些不足是根本原因。我对这段代码片段的了解:

  • “apply”方法将执行“emit”,“soc”作为“this”值并为“发射”方法提供“参数”(我就在这里请?)
  • socket.id 与socket 所有者的电子邮件有关,因为id.to(id) 是基于socket.id 是每个socket 与其自身连接的房间这一事实。 Redis提供了key-value数据结构,以用户邮箱为key,value为socket.id。

问题:

  • “争论”从何而来?
  • 这段代码的用途是什么?

请说清楚

最佳答案

此代码存在一些问题,但总体思路是为每个传入请求在 req 对象上定义一个方法 req.emitToUser()链中后面的一些其他路由处理程序使用该方法发送给发出请求的用户。这是一种普遍的愿望,希望将当前连接的 socket.io 连接连接到发出 http 请求的用户。

让我们看看这里的每一行:

redis.get(req.user.email, function(err, id) {

在 redis 数据库中查找 req.user.email 以获取与该电子邮件关联的 socket.io id,该电子邮件先前已保存在该 redis 数据库中。

if (err) next(err);

如果在 redis 中没有找到,则让这个请求失败并报错。

req.emitToUser = function() {

为当前的 req 对象分配一个新方法,以便链中后面的其他路由处理程序可以使用该方法。

 var soc = id && io.to(id);

在 socket.io 中查找 id 值以获取该 id 的套接字。从技术上讲,io.to() 不会返回套接字,但它会返回一个对象,您可以在该对象上调用 emit() 并将发送到该套接字。

soc.emit.apply(soc, arguments);

soc.emit.apply(soc, arguments);的作用是这样的:

  1. 执行soc.emit()方法
  2. soc 对象执行该方法时设置this 值。
  3. 在执行该方法时将参数设置为调用时传递给 req.emitToUser(x, y, z) 的任何参数。

这是一个更具体的例子:

function fn(a, b, c) {
console.log(a, b, c);
}

fn.apply(null, [1, 2, 3]);

使用 fn.apply(null, [1, 2, 3]); 将与:

fn(1, 2, 3);

现在,当参数已知时,您可能永远不会以这种确切的方式使用 .apply()。使用它的情况是当你有一些传递给你的任意数组(你不知道里面有什么)并且你想将这些参数传递给其他一些函数,顺序与给你的顺序完全相同.这就是 soc.emit.apply(soc, arguments); 正在做的事情。它采用 arguments 对象(这是一个类似数组的结构,表示传递给父函数 req.emitToUser() 的参数,并将这些确切的参数传递给它sock.emit()。如果您确切知道会有多少个参数,那么您可以硬编码相同的代码:

app.use(function(req,res,next) {
redis.get(req.user.email, function(err, id) {
if (err) next(err);
req.emitToUser = function(msg, data) {
var soc = id && io.to(id);
soc.emit(msg, data);
}
});
});

但是,.apply() 创建了一个更通用的解决方案,无论传递给 req.emitToUser() 的参数有多少,它都可以工作,因为它只会传递所有soc.emit() 的参数。


这行代码有点可疑:

var soc = id && io.to(id);

它似乎在试图防止没有从 redis 之前返回正确的 id。但是,如果没有 id,则 soc 将不是有效对象,下面的代码类似:

soc.emit.apply(soc, arguments);

会抛出。因此,id && io.to(id) 并没有真正提供适当的保护。看来这更可能是:

app.use(function(req,res,next) {
redis.get(req.user.email, function(err, id) {
if (err) next(err);
req.emitToUser = function() {
if (id) {
var soc = io.to(id);
soc.emit.apply(soc, arguments);
} else {
// not sure what you want here, perhaps return an error
// or throw a more meaningful exception
}
}
});
});

关于redis - 试图理解一篇关于 socket.io 和 redis 的文章的代码片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45063271/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com