简体   繁体   English

javascript function 使用 socket.io 作为回调传递给后端(节点)时未绑定“this”

[英]javascript function is not binding the 'this' when passed as a callback to the backend(node) using socket.io

One of my functions in the frontend is using ' this '.我在前端的功能之一是使用“ this ”。

function myFunction() {     
    ...     
    console.log(this);     
    ... 
}

I call it like this:我这样称呼它:

myFunction.call(objAsThis, param1, param2);

and everything is working as expected.一切都按预期进行。 But then I tried to pass this function to the backend(node.js) as a callback using socket.io :但是后来我尝试使用socket.io将这个 function 作为回调传递给后端(node.js):

Client客户

socket.emit("some event", param3, param4, myFunction);

Calling this function in node in the same way rendered some unexpected results.以同样的方式在节点中调用这个 function 出现了一些意想不到的结果。

Server服务器

socket.on("some event", function(param3, param4, myCbFunction) {     
    ...     
    myCbFunction.call(someObject, param5, param6);     
    ... 
});

I expect to see the someObject object printed but instead I get the socket.io 's ' this ' printed.我希望看到someObject object 被打印出来,但我得到的却是socket.io的 ' this ' 被打印出来。 Same story if I try to use bind:如果我尝试使用绑定,同样的故事:

myCbFunction.bind(someObject)(param5, param6);

I even tried(out of curiosity) calling it with new , which should have created a new object, but it didn't.我什至尝试(出于好奇)用new调用它,它应该创建一个新的 object,但它没有。 Outcome remained as before.结果一如既往。

new myCbFunction(param5, param6);

I get the same result( socket.io 's this ) if I just console.log(this) inside the “some event” event handler on the server.如果我只是在服务器上的“某些事件”事件处理程序中使用console.log(this) ,我会得到相同的结果( socket.io这个)。 So myCbFunction completely ignored the call , the bind or the new .所以myCbFunction完全忽略了callbindnew

Can someone please explain what is going on?有人可以解释这是怎么回事吗? Why it's not binding this to the object I provide?为什么它不将此绑定到我提供的 object?

OK, I think I see a source of confusion.好的,我想我看到了混乱的根源。

When you register this on the server:当您在服务器上注册时:

socket.on("some event", function(param3, param4, callback) {     
    ...
    callback(someArgs);
});

The point of callback() is to notify the client that you have received the message. callback()的作用是通知客户端您已收到消息。 It's referred to in the documentation as an ack function. This is NOT directly calling your client code.它在文档中称为ack function。这不是直接调用您的客户端代码。 In fact, this callback function is something that socket.io provides and when you call it you're calling socket.io, not calling the client.事实上,这个回调 function 是 socket.io 提供的,当你调用它时,你调用的是 socket.io,而不是调用客户端。 Instead, you call this function provided by socket.io and when socket.io receives this function call it packages up a message and sends that message back to the client over the socket.io connection.相反,您调用由 socket.io 提供的这个 function,当 socket.io 收到这个 function 调用时,它会打包一条消息并通过 socket.io 连接将该消息发送回客户端。 You call that ack function on the server when you want to tell the client that you've received the original message.当您想告诉客户端您已收到原始消息时,您可以在服务器上调用 ack function。

Keep in mind that client and server are nearly always on separate computers miles apart (always at oppositive ends of a TCP socket).请记住,客户端和服务器几乎总是位于相距数英里的不同计算机上(总是位于 TCP 套接字的两端)。 You can't directly call client code from the server.您不能直接从服务器调用客户端代码。

The client socket.io code will receive that ack message (and any serializable arguments you sent with it) and then will call the client side ack function that you specified here:客户端 socket.io 代码将收到该 ack 消息(以及您发送的任何可序列化的 arguments),然后将调用您在此处指定的客户端 ack function:

socket.emit("some event", param3, param4, myFunction);

You do not control the this value when this ack function is called - it will be whatever socket.io sets it to (unless you declare it as an arrow function).当调用此 ack function 时,您无法控制this值 - 它将是 socket.io 将其设置为的值(除非您将其声明为箭头函数)。 But, instead of passing your actual function, you can use a stub function and then reattach the desired this value before calling your real function.但是,您可以使用存根 function 而不是传递您的实际 function,然后在调用您的实际 function 之前重新附加所需的this值。

socket.emit("some event", param3, param4, function(...args) {
     myFunction.call(objAsThis, ...args)
});

This will then ignore the this value that the socket.io library passed to the callback and will attach the one you want.然后,这将忽略 socket.io 库传递给回调的this值,并附加您想要的值。 You could also use .bind() to do the same thing:你也可以使用.bind()做同样的事情:

socket.emit("some event", param3, param4, myFunction.bind(objAsThis));

which is just another way of passing a stub function as shown in the prior code solution.这只是另一种传递存根 function 的方法,如前面的代码解决方案所示。

And, if this was in the lexical context, you could also use an arrow function.而且,如果this是在词汇上下文中,您还可以使用箭头 function。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM