【问题标题】:JavaScript, node.js wait for socket.on response before continuingJavaScript,node.js 在继续之前等待 socket.on 响应
【发布时间】:2014-07-12 00:04:18
【问题描述】:

我需要从客户端的服务器获取信息。 所以在服务器端,当客户端第一次连接时我得到了这个:

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
}

在客户端我得到了这个:

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

我的问题是在socket on之外,播放器是没有定义的。似乎javascript在继续之前不会等待我的套接字打开来检索数据。

我尝试将 socket.on 包装在 $.when 完成后,但它不起作用。我尝试进行回调,但我想我可能不太了解它应该如何工作。所以如果你们中的一个愿意帮助我,我将不胜感激

感谢您的回答。

【问题讨论】:

    标签: javascript node.js sockets wait


    【解决方案1】:

    如果您将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);
        });
    }
    

    而不是做

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

    你会的

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

    “回调”在 Javascript 中有点传染性,这有点糟糕,但在每个人都开始使用生成器之前,生活就是这样。

    【讨论】:

    • 这就是 nodejs 存在 nibble 的原因
    • @LuisMasuelli:我找不到任何提及节点的“nibble”库。如果您的意思是“灵活”,那不是我的想法,因为它仍然迫使您使用库而不是现有的 JS 功能(如 while 循环或 try-catch)来执行控制流。见this
    • 可能是错误的名称。让我再检查一次... - 是的,你是对的。无论如何它很烂,但这是异步编程的警告
    • 在 getPlayer(function(player) 中我怎样才能在代码中的其他任何地方访问播放器?
    • @user3597823:“无处不在”是什么意思。基本上,这个想法是所有访问播放器的代码(由//... 表示)都需要在回调中移动。如果player 是某种全局变量,您也可以在回调中对其进行初始化,但您需要确保使用 blobal 的代码仅在初始化后才开始运行:getPlayer(function(p){ player = p; startGame(); })
    【解决方案2】:

    这是因为socket.on 运行时接受回调,并且在设置播放器的回调中。但是,在调用socket.on 之后,您尝试读取播放器,但它没有设置,因为没有调用回调。请记住,您正在处理异步编程。尝试在回调后使用nibble 链接该代码。

    记住:socket.on 和许多其他套接字处理程序 - 甚至许多其他事件句柄(例如 jquery)- 不要等待事件发生,因此您必须异步思考。

    举个例子:

    1. 您在套接字连接时调用 socket.on(连接需要 3 秒,例如,客户端位于 Tor 后面)。 socket.on 分配事件处理程序(这是它唯一做的事情,因为它以相同的方式适用于它拥有的 11 个或更多事件)。
    2. 您可以访问播放器。

    但是第 1 点不需要 3 秒,因为它只是一个分配 - 建立连接需要 3 秒。从这个意义上说,你有一个未定义(实际上:未分配)的变量。

    【讨论】:

      【解决方案3】:

      所有这些操作都是异步的,所以最好尽量避免全局变量和有状态。

      也就是说,让你的回调将新创建的 Player 对象带到它需要去的地方 - 也许是一个玩家寄存器? - 并以这种方式运输。

      callback(current_player)
      

      从那里,您可以根据需要将其放入全局可用的对象中,例如,如果您使用 Backbone 或在服务器端有一些东西来跟踪当前用户。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-01-17
        • 2019-04-23
        • 2020-01-18
        • 2016-04-02
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多