提问人:Alexander 提问时间:1/2/2023 更新时间:1/2/2023 访问量:75
JavaScript 函数在使用 socket.io 作为回调传递给后端(节点)时未绑定“this”
javascript function is not binding the 'this' when passed as a callback to the backend(node) using socket.io
问:
我在前端的一个功能是使用“this”。
function myFunction() {
...
console.log(this);
...
}
我这样称呼它:
myFunction.call(objAsThis, param1, param2);
一切都按预期进行。但后来我尝试使用 socket.io 将此函数作为回调传递给后端(node.js):
客户
socket.emit("some event", param3, param4, myFunction);
以相同的方式在 node 中调用此函数会呈现一些意外结果。
服务器
socket.on("some event", function(param3, param4, myCbFunction) {
...
myCbFunction.call(someObject, param5, param6);
...
});
我希望看到 someObject 对象被打印出来,但我却打印了 socket.io 的“this”。如果我尝试使用绑定,同样的故事:
myCbFunction.bind(someObject)(param5, param6);
我什至尝试(出于好奇)用new来称呼它,这应该创建一个新对象,但它没有。结果和以前一样。
new myCbFunction(param5, param6);
如果我只是在服务器上的“某个事件”事件处理程序中,我会得到相同的结果(socket.io 就是这样)。
因此,myCbFunction 完全忽略了调用、绑定或新调用。console.log(this)
有人可以解释一下这是怎么回事吗?为什么它没有将其绑定到我提供的对象?
答:
好吧,我想我看到了一个混乱的根源。
在服务器上注册时:
socket.on("some event", function(param3, param4, callback) {
...
callback(someArgs);
});
重点是通知客户端您已收到消息。它在文档中称为函数。这不是直接调用您的客户端代码。事实上,这个回调函数是 socket.io 提供的东西,当你调用它时,你是在调用 socket.io,而不是调用客户端。
相反,您可以调用 socket.io 提供的此函数,当 socket.io 收到此函数调用时,它会打包一条消息,并通过 socket.io 连接将该消息发送回客户端。当您想要告诉客户端您已收到原始消息时,可以在服务器上调用该 ack 函数。callback()
ack
请记住,客户端和服务器几乎总是位于相距数英里的不同计算机上(始终位于 TCP 套接字的对端)。不能直接从服务器调用客户端代码。
客户端 socket.io 代码将接收该 ack 消息(以及随它发送的任何可序列化参数),然后将调用您在此处指定的客户端 ack 函数:
socket.emit("some event", param3, param4, myFunction);
当调用此 ack 函数时,您无法控制该值 - 它将是 socket.io 设置的任何值(除非您将其声明为箭头函数)。但是,您可以使用存根函数,然后在调用实际函数之前重新附加所需的值,而不是传递实际函数。this
this
socket.emit("some event", param3, param4, function(...args) {
myFunction.call(objAsThis, ...args)
});
然后,这将忽略 socket.io 库传递给回调的值,并附加所需的值。你也可以用来做同样的事情:this
.bind()
socket.emit("some event", param3, param4, myFunction.bind(objAsThis));
这只是传递存根函数的另一种方式,如前面的代码解决方案所示。
而且,如果在词法上下文中,您还可以使用箭头函数。this
评论