前端函数经Socket.io传Node后端后无法绑定this的问题求助
问题:Socket.io传递函数回调后this绑定失效
我在前端有一个使用this的函数:
function myFunction() { ... console.log(this); ... }
使用myFunction.call(objAsThis, param1, param2);调用时一切正常。但当我通过Socket.io将该函数作为回调传给Node.js后端后出现异常:
客户端代码
socket.emit("some event", param3, param4, myFunction);
服务端代码
socket.on("some event", function(param3, param4, myCbFunction) { ... myCbFunction.call(someObject, param5, param6); ... });
我期望打印someObject,但实际输出的是Socket.io的this。尝试使用myCbFunction.bind(someObject)(param5, param6);甚至new myCbFunction(param5, param6);都无效,结果依旧。且在服务端的"some event"事件处理器内直接console.log(this)也得到Socket.io的this。为何myCbFunction完全无视call、bind、new的绑定?
原因分析
核心问题是Socket.io无法直接跨端传递函数本身,你传到服务端的并不是原函数myFunction,而是Socket.io生成的代理占位符。
Socket.io在跨端通信时仅支持JSON可序列化的数据,对于函数这类无法序列化的内容,它会做如下处理:
- 客户端发送函数时,Socket.io不会把函数代码发送到服务端,而是在本地注册这个函数并生成唯一标识,服务端收到的只是对应这个标识的代理函数。
- 当服务端调用这个代理函数时,本质是通过Socket.io向客户端发送执行指令,原函数
myFunction仍然在客户端环境执行,而非服务端。
这就解释了所有异常现象:
- 服务端调用
myCbFunction.call(someObject)时,someObject是服务端的对象,无法传递到客户端的函数执行环境,绑定操作自然无效; - 客户端执行
myFunction时,它的this默认绑定的是Socket.io客户端的上下文(也就是你看到的Socket.io的this),和服务端的任何绑定操作没有关系; - 服务端事件处理器里的
this是Socket.io服务端的上下文,和回调函数的this分属两个完全独立的运行环境,互不影响。
简单来说,你误以为函数在服务端执行,但它自始至终都在客户端运行,服务端只是触发了客户端的函数执行指令而已。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

