Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使JavaScript执行等待socket.on函数响应?_Javascript_Jquery_Node.js_Websocket_Socket.io - Fatal编程技术网

如何使JavaScript执行等待socket.on函数响应?

如何使JavaScript执行等待socket.on函数响应?,javascript,jquery,node.js,websocket,socket.io,Javascript,Jquery,Node.js,Websocket,Socket.io,这里,结果值是获得未定义的。如何将从socket.on函数中检索到的值分配给result变量并返回 这是接收socket.io消息事件的另一端 var data = bar(); function bar() { var result; socket.emit('message', 'test'); socket.on('msg', function(message) { result = message; }); return result; } 尝试返回

这里,结果值是获得
未定义的
。如何将从
socket.on
函数中检索到的值分配给
result
变量并返回

这是接收
socket.io
消息事件的另一端

var data = bar();

function bar() {
  var result;

  socket.emit('message', 'test');
  socket.on('msg', function(message) {
    result = message;
  });

  return result;
}

尝试返回确认中的对象。

var io = require('socket.io').listen(server);

io.sockets.on('connection', function(socket, username) {
  socket.on('message', function(message) {
    var result = 'test value'
    socket.emit('msg', result);
  });
});
另外,我试图通过一个简单的物体

io.sockets.on('connection', function (socket) {
    socket.on('message', function(message, ackCallback) {
        console.log("server received message", message);
        var result = tools.execute(message);  
        console.log(typeof(result)); // result is returned a object
        ackCallback(result);    
    });  
});
正在为此对象传递结果值


工具。执行(消息);正在返回此对象。它没有通过ackCallback传递

{uuid:'155C75EA-CB23-4172-85EB-3E256A271D8D', 名称:“”, 键入:“Object3D”, 父项:null, 儿童: [{uuid:'D778A19B-F935-4B06-8536-54494BC5F920', 名称:“”, 键入:“网格”, 父:[循环], 儿童:[], 向上:[反对], 位置:[对象], 旋转:[对象], 四元数:[对象], 比例:[对象], 矩阵:[对象], matrixWorld:[对象], matrixAutoUpdate:正确, matrixWorldNeedsUpdate:false, 图层:[对象], 可见:对, 卡斯特:错, receiveShadow:false, 沮丧的:是的, 渲染器:0, 用户数据:{}, 几何体:[对象], 材料:[对象], drawMode:0}, {uuid:'9FD1CACF-6A2B-4932-8FA2-B0A4AF618F8D', 名称:“”, 键入:“网格”, 父:[循环], 儿童:[], 向上:[反对], 位置:[对象], 旋转:[对象], 四元数:[对象], 比例:[对象], 矩阵:[对象], matrixWorld:[对象], matrixAutoUpdate:正确, matrixWorldNeedsUpdate:false, 图层:[对象], 可见:对, 卡斯特:是的, receiveShadow:false, 沮丧的:是的, 渲染器:0, 用户数据:{}, 几何体:[对象], 材料:[对象], drawMode:0}], 向上:{x:0,y:1,z:0}, 位置:{x:0,y:0,z:0}, 轮换: {ux:0, _y:0, _z:0, _订单:“XYZ”, onChangeCallback:[函数:onRotationChange]}, 四元数: {ux:0, _y:0, _z:0, _w:1, onChangeCallback:[函数:onQuaternionChange]}, 比例:{x:1,y:1,z:1}, 矩阵:{元素:Float32Array[1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1]}, matrixWorld:{elements:Float32Array[1,0,0,0,0,1,0,0,0,0,1]}, matrixAutoUpdate:正确, matrixWorldNeedsUpdate:false, 层:{mask:1}, 可见:对, 卡斯特:错, receiveShadow:false, 沮丧的:是的, 渲染器:0, userData:{}

您不能“让Javascript等待”异步事件发生。Javascript不是这样工作的。它是一个事件驱动的体系结构,根本不能以这种方式工作

另外,当通过某种异步操作获得某个值时,无法直接从函数返回该值。该函数将在值准备就绪之前很久返回。您可以在这里看到有关为什么会出现这种情况的详细信息以及关于该一般主题的一些选项

处理异步结果的现代方法是返回一个承诺,该承诺将在事件发生时得到解决,然后调用方可以使用该承诺获得最终结果

var result = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
ackCallback(result);
我在这里展示的是一个更高级的版本,它还实现了一个超时,因此如果在一段时间内没有收到响应,承诺将被拒绝。这是为了避免创造一个承诺,这个承诺可能永远挂在那里,永远得不到回应,因此永远无法解决


注意:如果您使用socket.io实现某种请求/响应,您可以从第一条消息中获得直接响应,这是使用socket.io响应特定请求的更好方法。您可以看到
ack
回调选项如何用于
socket.emit()
。要使用它,您需要连接两端的合作。发送消息并指定
ack
回调。然后,消息的接收者提供一些
ack
数据,您的
ack
回调将接收这些数据。这将是对您的邮件的直接响应,如果同时也有对同一邮件的其他请求,则不会让您的邮件混淆。对于socket.io中的请求/响应,这是首选体系结构。为了向您展示如何实现它的完整代码示例,我们必须看到代码的另一端接收socket.io
消息
事件


好的,现在您已经显示了连接的另一端,您可能应该使用socket.io的
ack
响应功能:

function bar(data, timeout = 10000) {
    return new Promise((resolve, reject) => {
        let timer;

        socket.emit('message', data);

        function responseHandler(message) {
            // resolve promise with the value we got
            resolve(message);
            clearTimeout(timer);
        }

        socket.once('msg', responseHandler); 

        // set timeout so if a response is not received within a 
        // reasonable amount of time, the promise will reject
        timer = setTimeout(() => {
            reject(new Error("timeout waiting for msg"));
            socket.removeListener('msg', responseHandler);
        }, timeout);

    });
}

bar().then(message => {
   // you can use message here and only in here
});
服务器端:

function bar(timeout = 10000) {
    return new Promise((resolve, reject) => {
        console.log("client sending message 'test');
        socket.emit('message', 'test', function(response) {
            console.log("client got ack response", response);
            resolve(response);
        });
    });
}

bar().then(message => {
   // you can use message here and only in here
   console.log("response from bar(): ", message);
});

另外,您的服务器端代码在此处显示了一个
username
参数:

var io = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
    socket.on('message', function(message, ackCallback) {
        console.log("server received message", message);
        var result = 'test value'
        console.log("server sending back result", result);
        ackCallback(result);    
    });  
});
没有这样的
username
参数传递给该事件处理程序,因此我不确定您从何处获得该参数。您的代码没有实际使用它,所以我只是删除了它(因为它无论如何都是无效的)。

您不能“让Javascript等待”异步事件发生。Javascript不是这样工作的。它是一个事件驱动的体系结构,根本不能以这种方式工作

另外,当通过某种异步操作获得某个值时,无法直接从函数返回该值。该函数将在值准备就绪之前很久返回。您可以在这里看到有关为什么会出现这种情况的详细信息以及关于该一般主题的一些选项

处理异步结果的现代方法是返回一个承诺,该承诺将在事件发生时得到解决,然后调用方可以使用该承诺获得最终结果

var result = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
ackCallback(result);
我在这里展示的是一个更高级的版本,它还实现了一个超时,所以如果在一段时间内没有收到响应,