2

I have a js function called listClients. It makes a socket.io emit request to grab a list of clients from a node.js server which uses fs to read a file and then send the data back to the client through a callback.

I need to return the callback data to the original function so clients can execute the function and use the data which it returns, but it's not working due to the callback being wrapped in it's own function. What's the best way to work around this?

Client:

function listClients() {
    var sender = getCookieData('relay_client_id');

    if (sender) {
        socket.emit('list_relay_clients', sender, (callback) => {
            return callback; //This won't work because it's async
        });

        return callback; //<---- I need it to be here
    }
}

Server:

socket.on('list_relay_clients', function (sender, callback) {
    callback(fetchAllClients());
});
Sammyjo20
  • 79
  • 2
  • 9
  • in other side you also pass data through event emit same as like right now you did for list_relay_clients – Dipak Feb 10 '18 at 17:00
  • I did try that, and It gave me the same result. I need to somehow grab the data from the emit callback and then pass it as the return value of the original function... – Sammyjo20 Feb 10 '18 at 17:02
  • can you put your working snippet here? – Dipak Feb 10 '18 at 17:03
  • Not really because it's using a node.js server and socket.io – Sammyjo20 Feb 10 '18 at 17:06
  • but I would like to know your code snippet how did you try it – Dipak Feb 10 '18 at 17:06
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Patrick Roberts Feb 13 '18 at 20:25

1 Answers1

1

This is more of a basic JS and async execution problem. You have a Async call and your want to return a synchronous output. This is not the right thing to do though. So you should start looking at promises in this case

function listClients() {
    return new Promise( resolve => {
    var sender = getCookieData('relay_client_id');

    if (sender) {
        socket.emit('list_relay_clients', sender, (callback) => {
            resolve(callback)
        });
    }
    });
}

Then the users of the function should call this function in below way

listClients().then(data=>console.log(data))

If they are not interested in waiting like this and they have async/await JS functionality available then they can use

async function clientCode() {
   let clientData = await listClients();
}

If you still further like to make it synchronous read the below article

http://www.tivix.com/blog/making-promises-in-a-synchronous-manner

But since JS is async, a operation which involves a network call, you should try to keep it async, trying to make it a sync one is not a good practice

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265