Untangling with promises

In my Ephemeral Exchange project, I use socket.io to handle push notifications when any cache values are updated, are deleted or expire. Where you have a lot of asynchronicity going on, it can be hard to deal with all the callbacks.

For example, let’s say that you try to set up a push notification – which then uses (or creates) a socket.io connection, and then set up another before the connection is complete, you would create a new connection unless you are tracking that there is already a connection in progress – but even then how do you communicate back to the second requestor when the first requestor is finished.

All this is made very easy to orchestrate with promises – Here’s how the conversation to asynchronously connect and authenticate with socket.io can be simplified.

The caller

The caller would like to get a socket, or use one that is already in place (or in the progress of being in place). The socket is managed centrally for a single client, so the first step is to make one if we don’t have one.
This is not asnynchronous, so is not troublesome.
Next, we can use the getConnected method – which simply returns a promise. The same promise is used by all connection attempts, so either we already have one, one is in progress or this is the first attempt. The great thing is you don’t need to care which.

The socketing namespace

Here’s what getConnected looks like in the Socketing namespace – it returns the current promise for connection status, or kicks one off if there isn’t one.

Now lets’ take a look at the connect_ function, which actually has the conversation with the socket.io server
The server conversation is a little more complex since it has to manage server events, timeouts and also authenticate using a passphrase. However this, too can be broken down into promises. Here’s the sequence of events
First the connectionEvent
Now the passphrase conversation
And the timeout function is also a promise
And finally, deal with disconnect events. The key here is to set the getConnected_ promise to null, so future attempts will initiate a connection again.
For more on this topic, see: