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 that checkReturn
is first finished and only then the rest of the code gets executed?
socket io relies on websockets and websockets rely on tcp that guarantees that packets will be received in the samr order they are sent.
socket. emit() happens to return the socket itself (allows for method chaining). But, that's not relevant here because there's no point in returning any value from a Promise executor function. If you do return a value, it is not used by the Promise in any way.
JS, Socket.IO enables asynchronous, two-way communication between the server and the client. This means that the server can send messages to the client without the client having to ask first, as is the case with AJAX.
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 });
});
});
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));
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With