socket.io - socket.on wait for promise

16,618

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); } } });    
});
Share:
16,618
Tamas
Author by

Tamas

Full Stack Web Developer turned Technical Instructor, Curriculum Developer, Developer Evangelist and Google Developer Expert in Web Technologies.

Updated on June 19, 2022

Comments

  • Tamas
    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 that checkReturn is first finished and only then the rest of the code gets executed?

  • Tamas
    Tamas over 10 years
    so I should just wrap everything inside the socket.on call?
  • Tamas
    Tamas over 10 years
    this 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
    hexacyanide over 10 years
    The 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
    Tamas over 10 years
    Thanks, I appreciate it.
  • Elfayer
    Elfayer almost 9 years
    Your example is kind of weird... Names doesn't match. See the doc example here : socket.io/docs/#sending-and-getting-data-%28acknowledgements‌​%29