NodeJS&Socket.IO:发出请求事件并获取响应,我应该在何时何地绑定侦听器?

Max*_*aux 5 javascript node.js socket.io

我目前想知道在这种情况下什么是最佳编程实践:

假设我已将客户端连接到服务器。该客户端正在向服务器请求auth事件及其用户名的身份验证。

socket = io();
socket.emit('auth', "John");
Run Code Online (Sandbox Code Playgroud)

在这种简单情况下,服务器将使用auth_succeed带有用户ID 的事件进行响应。

io.on('connection', function(socket) {
    socket.on('auth', function(username) {
        socket.emit('auth_succeed', id);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,我应该在何时或何地auth_succeed在客户端中绑定事件的侦听器?我有两种方法:

我猜,在发出之前,这确保了响应事件将始终得到正确处理,但会导致一些意大利面条式代码。例如:

socket = io();
socket.on('auth_succeed', function(id){
    //Do some post-auth stuff here
}); 
socket.emit('auth', "John");
Run Code Online (Sandbox Code Playgroud)

或者在发出之后,这会导致代码更简洁,但是如果再次发送得足够快,我可能又会错过该事件。例如:

socket = io();
socket.emit('auth', "John");
socket.on('auth_succeed', function(id){
    //Do some post-auth stuff here
}); 
Run Code Online (Sandbox Code Playgroud)

您对该问题有何看法?

Tra*_*er1 6

由于发出的响应应该是异步的,并且客户端JS本质上是同步的,因此socket.on('auth_succeed'绑定将发生在auth事件的回调之前。


以下流程将在客户端上发生...

// EXECUTION SCOPE BEGINS
...
// this will send a message to the server
// the message and/or response will be sent asynchronously
socket.emit('auth', 'John'); 
// so your code will continue before you get anything from the server

//which means the following binding will happen before any response to the above emit
socket.on('auth_succeed', function(id){
  //... handle message from server ...
});
...
// EXECUTION SCOPE ENDS
Run Code Online (Sandbox Code Playgroud)

封闭范围/功能完成后的某个时间,将引发“ auth_succeed”事件。


您可能还需要考虑突破您的事件处理程序...

socket.on('auth_succeed', onAuthSucceed.bind(null, socket));
socket.emit('auth', 'john');

// ... elsewhere ...

function onAuthSucceed(socket, id) {
  // handle message from server
}
Run Code Online (Sandbox Code Playgroud)

无论您选择先绑定还是发出信号,这都会降低绑定和信号事件的噪音。

通过让函数需要它所需要的任何东西,并为事件使用绑定,可以将所讨论的方法放在单独的文件/模块中,并且更容易单独进行测试。