socket.io - socket.on 等待承诺

Posted

技术标签:

【中文标题】socket.io - socket.on 等待承诺【英文标题】:socket.io - socket.on wait for promise 【发布时间】:2013-11-05 16:45:15 【问题描述】:

我有一个按钮可以与服务器进行一些通信,以检查输入的值(通过输入框)是否已经存在。代码如下:

$("#button").click(function () 
    var exists = false;
    var name = $("#name").val();
    socket.emit("check", name);

    socket.on("checkReturn", function (data) 
        exists = data.result;
    );

    if (exists) 
        console.log("exists")
     else 
        if (name.length > 0) 
            socket.emit("create", name);
        
    
);
);

问题在于checkReturn 调用是异步的,因此代码继续执行而不实际等待结果。如何确保 checkReturn 首先完成,然后才执行其余代码?

【问题讨论】:

【参考方案1】:

除了其他答案,您还可以使用确认,在客户端和服务器之间传递回调。然后就可以直接使用emit函数的回调了:

$("#button").click(function() 
  var exists = false; 
  var name = $("#name").val(); 

  socket.emit('check', name, function (data)  
    exists = data.result;
    if (exists) console.log("exists");
    else (if (name.length > 0) socket.emit("create", name));
  );
);

在服务器端它看起来像这样:

io.sockets.on('connection', function (socket) 
  socket.on('ferret', function(name, fn) 
    // find if "name" exists
    fn( exists: false );
  );
);

【讨论】:

这个解决方案对我来说效果更好。你能用几行解释一下 fn() 回调是如何工作的吗?我无法理解它。 fn() 是一个回调函数。在 javascript 中,您可以将一个函数传递给另一个函数,然后再调用它。在这种情况下,Socket.IO 实现了“确认”,您将一个函数传递给服务器,然后服务器调用该函数。 谢谢,非常感谢。 您的示例有点奇怪...名称不匹配。请参阅此处的文档示例:socket.io/docs/#sending-and-getting-data-%28acknowledgements%29【参考方案2】:

@hexacyanide aswer 的替代方法可以这样做:

$("#button").click(async function() 
  var exists = false; 
  var name = $("#name").val(); 

  exists = await new Promise(resolve => socket.emit('check', name, data => resolve(data.result)))

  if (exists) console.log("exists");
  else (if (name.length > 0) socket.emit("create", name));
);

套接字发射被包裹在一个承诺中,因此它可以等待回调,并避免嵌套在多个花括号内。

不是那么优雅,但如果将代码封装在一个单独的函数中,可以使您的代码更易于阅读:

function check(name)
  return new Promise(resolve => socket.emit('check', name, data => resolve(data.result)))

并像这样使用:

$("#button").click(async function() 
  var exists = false; 
  var name = $("#name").val(); 

  exists = await check(name)

  if (exists) console.log("exists");
  else (if (name.length > 0) socket.emit("create", name));
);

【讨论】:

【参考方案3】:
$("#button").click(function () 
 var exists = false; 
var name = $("#name").val(); 
socket.emit("check", name);

socket.on("checkReturn", function (data)  
exists = data.result;
if (exists)  console.log("exists")  else  if (name.length > 0)  socket.emit("create", name);   );    
);

【讨论】:

所以我应该把所有东西都包装在 socket.on 调用中?【参考方案4】:

您可以使用 socket.io.wait 从 socket.io 获取同步响应:

https://www.npmjs.com/package/socket.io.wait

$("#button").click(async function ()

    var exists = false;
    var name = $("#name").val();

    let exists = await socket.emitWait("check", name);


    if (exists == true)
    
        console.log("exists");
     
    else
    
        if (name.length > 0)
        
            socket.emit("create", name);
        
    
);

【讨论】:

以上是关于socket.io - socket.on 等待承诺的主要内容,如果未能解决你的问题,请参考以下文章

socket.io - socket.emit、socket.on、socket.send

Angular 6 和 Socket.IO - Socket.On 不工作

socket.io - 多次加载视图时,socket.on 方法也会运行多次

socket.io 发射在 socket.on 中不起作用

与 Socket.io 反应 - 在“socket.on”事件上不断地重新渲染

用户杀死应用程序后,Socket.io android socket.on 不起作用