最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript, node.js wait for socket.on response before continuing - Stack Overflow

programmeradmin4浏览0评论

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.

I tried to wrap socket.on in a $.when done, but it doesn't work. 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.

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.

I tried to wrap socket.on in a $.when done, but it doesn't work. 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.

Share Improve this question asked May 22, 2014 at 19:22 user3597823user3597823 551 silver badge6 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

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

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.

This is since socket.on runs taking a callback, and is in the callback where the player is set. however, after calling socket.on you try to read the player, but it is not set, since the callback was not called. Remember you're dealing with asynchronous programming. Try using nibble to chain that code after the callback.

Remember: socket.on and many other socket handlers -and even many other event handles (e.g. jquery)- DON'T wait to the event to happen, so you must think asynchronously.

Take this example:

  1. You call socket.on while the socket is connecting (The connection takes 3 seconds since, e.g., the client is behind 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).
  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. 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? - 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.

发布评论

评论列表(0)

  1. 暂无评论