question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add `socket.request()` as promise wrapper around callbacks

See original GitHub issue

I noticed that in the 4.4.0 release, a timeout flag was added:

socket.timeout(5000).emit("my-event", (err) => {
  if (err) {
    // the client did not acknowledge the event in the given delay
  }
});

Interestingly I implemented similar logic in an application of mine by patching client-side sockets, but I combined it with promises as well. Something like

await socket.request('event', 'some data');

where the promise times out after a fixed amount of time if the server did not acknowledge.

As a result, I was wondering whether it would a nice feature to add to the library as well. The api would look something like

// Awaits indefinitely for a server response
await socket.request('event', 'some data');

// Times out after 5 seconds
await socket.timeout(5e3).request('event', 'some data');

This could be accompanied by a reply() and replyAny() method as well of course, which looks something like this and hence hides the callbacks from the user alltogether:

socket.reply('event', async (data) => {
  return res.toJSON();
});
socket.reply('event', async (...data) => {
  throw new Error('Something went wrong');
});
socket.replyAny(async (event, ...data) => {
  return res.toJSON();
});

Additionally I think it might be useful to have a way of resurrecting errors as well, but I’m not sure how the api can look like. Perhaps something like

socket.errorBuilder(json => buildCustomErrorFromJSON(json));

or

io.errorBuilder(json => buildCustomErrorFromJSON(json));

where socket.errorBuilder can be used to override for that socket.

As always, I’d be happy to create a PR for this should you decide that it is a feature that is desirable to have in the library. In my opinion it fits nicely in the trend that callbacks are more and more being replaced by promises.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:5
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

8reactions
darrachequesnecommented, Nov 23, 2021

@sebamarynissen that makes sense 👍

Let’s keep this issue open, to see if other users want this functionality to be built-in.

0reactions
MiniSuperDevcommented, Nov 28, 2022

I would like this functionality, and it also helps to write code and tests more readable using async await syntax.

But I’m not convinced by the name request, as I understand, the idea is to allow to change the callback syntax of acknowledgement for an await async syntax, so in this way, and without breaking changes and aligned with current naming convention this would be better

  • emitWithAck

and in the same way reply should be onWithAck , although I still see a lot of use for this one, so I appreciate if someone would like to show me an example where it would be useful to use await async when registering event handlers

For example this: https://github.com/socketio/socket.io/blob/3b7ced7af7e0a2a66392577f94af1ee5ed190ab1/examples/basic-crud-application/server/test/todo-management/todo.tests.ts#L165-L200

to something like this;

describe('update todo', () => {
  it('should update a todo entity', async () => {
    const todoId = 'c7790b35-6bbb-45dd-8d67-a281ca407b43';
    todoRepository.save({
      id: todoId,
      title: 'lorem ipsum',
      completed: true,
    });

    const todoUpdated = {
      id: todoId,
      title: 'dolor sit amet',
      completed: true,
    };

    const onTodoUpdated = jest.fn();

    otherSocket.on('todo:updated', onTodoUpdate);

    await socket.emitWithAck('todo:update', todoUpdated);

    const storedEntity = await todoRepository.findById(todoId);

    expect(storedEntity).toEqual(todoUpdated);
    expect(onTodoUpdated).toBeCalledWith(todoUpdated);
  });
});

Is there any plan to implement it?

Thank you.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Wrap socket.on as a promise - javascript
I am making a service, with a function init as resolve . First, it creates a folder with the id of the connection,...
Read more >
Understanding the Event Loop, Callbacks, Promises, and ...
The event loop checks the queue for any pending messages and finds the anonymous function from setTimeout() , adds the function to the...
Read more >
Promises and Events: Some Pitfalls and Workarounds
Promises make it possible to express the strict requirements we have on the execution order of asynchronous code. No nested callbacks necessary!
Read more >
ws-wrapper
ws-wrapper. Lightweight and isomorphic Web Socket lib with socket.io-like event handling, Promise-based requests, and channels.
Read more >
Learning ES6: Promises - Engineering Blog
Creating a promise wrapper for setTimeout ... The error callback ( catch() ) is particularly convenient for two reasons:.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found