3

Is the following somehow possible?

async function doesSocketAgree(){
    socket.emit('doesOtherSocketAgree', otherSocketId);
    await socket.on('responseDoesSocketAgree', (answer)=>{
      console.log('answer');
});
}

2 Answers 2

6

In socket.io you can use "acknowledgements" callbacks:

async function doesSocketAgree(){
  await new Promise(resolve => {
    socket.emit('doesOtherSocketAgree', otherSocketId, (answer) => {
      resolve(answer);
    });      
  });
}

https://socket.io/docs/#Sending-and-getting-data-acknowledgements

So you can use a single emit() and can trigger a callback. That has the advantage you dont have to deal with memory leaks from register an event listener every time you call this function.

1
  • This is likely the best way to do this.
    – jfriend00
    Commented Feb 18, 2020 at 1:26
4

It is, but not that way. You'll have to wrap things in a promise so that you can "return" from your await once data comes in as part of your "on" handling:

async function doesSocketAgree(){
  socket.emit('doesOtherSocketAgree', otherSocketId);
  await new Promise(resolve => {
    socket.on('responseDoesSocketAgree', answer => {
      resolve(answer);
    });
  });
}

And you probably want to remove that listener before you call resolve() so that it doesn't keep on triggering, because every time you call doesSocketAgree() you'd be adding a new listener to the "on:responseSocketAgree" pile. So that'll end up going wrong pretty quickly without cleanup.

On that note, you probably want to emit your "does it agree?" with a random token that your on handler can verify is the one that's scoped to the current function call, "because async".

3

Not the answer you're looking for? Browse other questions tagged or ask your own question.