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 方法也会运行多次