socket.io - socket.on wait for promise
Solution 1
Aside from the other answer, you can also use acknowledgements, where a callback is passed between the client and server. Then you can just use the callback of the emit function:
$("#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));
});
});
On the server side it would look like this:
io.sockets.on('connection', function (socket) {
socket.on('ferret', function(name, fn) {
// find if "name" exists
fn({ exists: false });
});
});
Solution 2
An alternative for @hexacyanide aswer could be done like that:
$("#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));
});
The socket emit is wrapped inside a promisse so it can wait for the callback, and avoid the nesting inside multiple curly braces.
Is not that elegant, but could make your code easier to read if it is encapsulated inside a separated function:
function check(name){
return new Promise(resolve => socket.emit('check', name, data => resolve(data.result)))
}
And used like such:
$("#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));
});
Solution 3
You can use socket.io.wait to get synchronous responses from 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);
}
}
});
Solution 4
$("#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); } } });
});
Tamas
Full Stack Web Developer turned Technical Instructor, Curriculum Developer, Developer Evangelist and Google Developer Expert in Web Technologies.
Updated on June 19, 2022Comments
-
Tamas almost 2 years
I have a button that does some communication with the server to check if an entered value (via an input box) already exists. The code is the following:
$("#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); } } }); });
The problem is that the
checkReturn
call is asynchronous, and therefore the code carries on without actually waiting for the result. How do I make sure thatcheckReturn
is first finished and only then the rest of the code gets executed? -
Tamas over 10 yearsso I should just wrap everything inside the socket.on call?
-
Tamas over 10 yearsthis solution works much better to me. can you explain to me a in a few lines how does that fn() callback work exactly? I can't get my head around it.
-
hexacyanide over 10 yearsThe
fn()
is a callback function. In JavaScript, you can pass one function to another, and then call it later. In this case, Socket.IO implemented "acknowledgements", where you pass a function to the server, and the server calls that function. -
Tamas over 10 yearsThanks, I appreciate it.
-
Elfayer almost 9 yearsYour example is kind of weird... Names doesn't match. See the doc example here : socket.io/docs/#sending-and-getting-data-%28acknowledgements%29