【问题标题】:Asynchronous socket.io javascript callback not working异步socket.io javascript回调不起作用
【发布时间】:2014-10-24 14:54:54
【问题描述】:

我需要帮助使我的 javascript 异步,因为我正在使用 node.js 从数据库中查询。我正在使用 node.js 和 socket.io。如果我使用 setTimeout() 函数,代码可以工作,但我想让我的代码更可靠,所以我正在尝试实现回调。但是,我不知道如何在回调函数中正确使用“socket.on()”。我认为问题在于我正在嵌套 socket.on 调用,而第二个“socket.on()”调用没有执行。任何帮助将不胜感激,谢谢。

/*server side*/
socket.emit(variable1);//not important
socket.emit(variable2);//not important
//code above isn't important, I just wanted to show how data is used from my queries



/*client side*/
var socket = io.connect('123.456.789.123:3000');
var data = " ";//data I need to pass around


   socket1(data, function(){
        socket2(data)
   });


   function socket1(data, callback) {
        socket.on('variable1', function (data)  {
            console.log("1");
            callback();
        }, callback)
    }

    function socket2(data) {
        console.log("2");
        socket.on('variable2', function (data) {
            console.log("3");
        })
    }

输出为“12” 应该是“123”

【问题讨论】:

    标签: javascript node.js asynchronous callback socket.io


    【解决方案1】:

    将异步函数调用视为注册处理程序的注册过程,以便在从服务器接收到数据作为推送时注册处理程序。

    function registerVariable1(callback) {
    
        socket.on('variable1', function (data)  {
            console.log("1");
            callback(data);
        });
    }
    
    function registerVariable2(callback) {
    
        socket.on('variable2', function (data)  {
            console.log("2");
            callback(data);
        });
    }
    

    在服务器上,当您向客户端发送数据时,使用处理程序的名称作为第一个参数,如 here 所述。

    socket.emit('variable1', {data: 1});
    socket.emit('variable2', {data: 2});
    

    这会将数据发送到正确的处理程序。

    话虽如此,您可能想错了。不要将每个处理程序视为特定于单个操作。将此视为向服务器注册一个侦听器,以便服务器可以继续将数据发送回该处理程序。 registerVariable1 和 registerVariable2 都只需要调用一次,然后你的服务器就可以向每个 handler 推送 N 次数据。

    要注册处理程序,您只需将回调函数传入每个处理程序:

    registerVariable1(function(data) {
        console.log('This is the first handler');
        console.log(data);
        // do stuff for this handler here...
    });
    
    registerVariable2(function(data) {
        console.log('This is the second handler');
        console.log(data);
        // do stuff for this handler here...
    });
    

    现在,如果服务器进行以下三个调用:

    socket.emit('variable1', {data: 123});
    socket.emit('variable2', {data: 24});
    socket.emit('variable1', {data: 22});
    

    您可能会看到以下输出:

    1
    This is the first handler
    {data: 123}
    2
    This is the second handler
    {data: 24}
    1
    This is the first handler
    {data: 22}
    

    订单可能无法保证;但是,因为您正在处理网络。但希望这可以帮助您了解其工作原理。

    【讨论】:

    • 您好,感谢您的深入解释!我的服务器代码只能发出一次,因为它是在从数据库进行查询之后发出的。我按照您指定的方式实现了我的代码,并且正在打印输出,但是这些方法以错误的顺序 (2,1) 打印出来。有没有办法确保 registerVariable1() 在 registerVariable2() 被调用之前完全执行并完成?这就是我想要实现的目标,也许服务器端是问题所在,但我不能多次查询,所以每个处理程序只能发出一组数据。希望这是有道理的。再次感谢!
    • 听起来您的问题不是服务器端,而是客户端。听起来您在发出数据时拥有数据库中的所有数据,因此您可以在 JSON 对象中发出它,然后单独处理该数据,不是吗?
    • 换句话说,socket.emit({varOne: dataForVar1Here, varTwo: dataForVar2Here}); 一次性发送所有数据,这就是我的意思...
    • 谢谢@Mike。 Socket.IO 团队应该在他们的文档中使用不同的永久链接。什么样的恶梦。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多