简体   繁体   English

JavaScript,node.js在继续之前等待socket.on响应

[英]JavaScript, node.js wait for socket.on response before continuing

I need to get information from the server on the client side. 我需要从客户端的服务器获取信息。 So on the server side I got this when a client first connect: 所以在服务器端,我在客户端第一次连接时得到了这个:

socket.on('adduser', function(username){
    // misc code, where i set num_player and whatnot
    socket.emit('confirmauth', socket.id, socket.num_player, function(data){
         console.log(data)
    });
    // code
}

and on the client side I got this: 在客户端我得到了这个:

var current_player;
socket.on('confirmauth', function(id, username, num, callback) {

    current_player = new Player(username,id, num);

    console.log(current_player.id); // works
    console.log(current_player.num); //works
    callback('ok i got it');
});

console.log(current_player.id); //undefined
console.log(current_player.num); //undefined

my problem is that outside of the socket on, the player is not defined. 我的问题是在套接字之外,播放器没有定义。 It seems that javascript doesn't wait for my socket on to retrieve data before carrying on. 似乎javascript不会等待我的套接字在继续之前检索数据。

I tried to wrap socket.on in a $.when done, but it doesn't work. 我尝试将socket.on包装在$ .when中,但它不起作用。 I tried to do a callback, but I think I may not have understood very well how it is supposed to work. 我试图做一个回调,但我想我可能不太了解它应该如何工作。 So if one of you is willing to help me, I will be grateful 所以,如果你们中的一个愿意帮助我,我将不胜感激

Thank you for your answers. 谢谢您的回答。

If you are putting the current_player variable outside of the on callback in an attempt to return it, the alternative is to make your own function receive a callback 如果你将current_player变量放在on回调之外试图return它,另一种方法是让你自己的函数接收回调

function getPlayer(onDone){
    socket.on('confirmauth', function(id, username, num, callback) {
        var current_player = new Player(username,id, num);
        onDone(current_player);
    });
}

And instead of doing 而不是做

var player = getPlayer();
//...

You do 你做

getPlayer(function(player){ 
    //...
});

It kind of sucks that the "callbackyness" is a bit infectious in Javascript but such is life until everyone starts using Generators instead. 有点糟糕的是,“回调”在Javascript中有点传染性,但这种生活直到每个人都开始使用生成器。

This is since socket.on runs taking a callback, and is in the callback where the player is set. 这是因为socket.on运行回调,并且在回调中设置了播放器。 however, after calling socket.on you try to read the player, but it is not set, since the callback was not called. 但是,在调用socket.on你尝试读取播放器,但是没有设置,因为没有调用回调。 Remember you're dealing with asynchronous programming. 记住你正在处理异步编程。 Try using nibble to chain that code after the callback. 尝试使用nibble在回调后链接该代码。

Remember: socket.on and many other socket handlers -and even many other event handles (eg jquery)- DON'T wait to the event to happen, so you must think asynchronously. 记住: socket.on和许多其他套接字处理程序 - 甚至许多其他事件句柄(例如jquery) - 不要等到事件发生,所以你必须异步思考。

Take this example: 举个例子:

  1. You call socket.on while the socket is connecting (The connection takes 3 seconds since, eg, the client is behind Tor). 在套接字连接时调用socket.on (连接需要3秒钟,例如,客户端在Tor后面)。 socket.on assigns the event handler (it's the only thing it does since it works for the 11 or more events it has, in the same way). socket.on分配事件处理程序(它是唯一的事情,因为它适用于它拥有的11个或更多事件,以同样的方式)。
  2. You access the player. 您可以访问播放器。

But the point 1 does not take 3 seconds since it's just an assignment - the connection is what takes 3 seconds to be established. 但是点1不需要3秒,因为它只是一个任务 - 连接需要3秒才能建立。 In that sense, you have an undefined (actually: unassigned) variable. 从这个意义上说,你有一个未定义的(实际上是:未分配的)变量。

All of these operations are asynchronous, so it's best to avoid global variables and statefulness as much as possible. 所有这些操作都是异步的,因此最好尽可能避免全局变量和有状态。

That said, have your callback take the newly created Player object to where it needs to go - a register of players, maybe? 那就是说,让你的回调将新创建的Player对象带到它需要去的地方 - 也许是一个玩家注册? - and transport it that way. - 并以这种方式运输。

callback(current_player)

From there, you can put it into a globally available object as you like, for instance if you're using Backbone or have something on the server side keeping track of current users. 从那里,您可以根据需要将其放入全局可用对象中,例如,如果您正在使用Backbone或在服务器端有一些东西跟踪当前用户。

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

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