Effection Logo

Events

Asynchronous code often needs to interact with evented code. Using async/await this can be quite challenging. Evented code often needs to be synchronous, because the timing of when to subscribe and unsubscribe is very critical, otherwise race conditions can occur where events get missed. Effection has convenient apis to ensure that you never run into these problems.

Single events

The simplest operation for working with events that Effection provides is the once() operation. This operation works with any EventTarget and blocks until one of its events occurs. For example, consider that we wanted to wait for the open event on a WebSocket, we could do something like this:

import { main, once } from 'effection';

await main(function*() {
  let socket = new WebSocket('ws://localhost:1234');

  yield* once(socket, 'open');

  console.log('socket is open!');
});

The once operation returns the argument passed to the event handler. For example we could use this to grab the code that the socket closed with:

import { main, once } from 'effection';

await main(function*() {
  let socket = new WebSocket('ws://localhost:1234');

  yield* once(socket, 'open');

  console.log('socket is open!');

  let closeEvent = yield* once(socket, 'close');
  console.log('socket closed with code', closeEvent.code);
});

Recurring events

If you've been following the chapter on streams and subscriptions, you may already have a feeling that it is not a good idea to repeatedly call once(socket, 'message') to grab the messages sent to a WebSocket. The risk here is that we miss messages if we're not very careful.

Instead we can use on(). on() is a very convenient function which takes an event target and the name of an event, and returns a Stream of values corresponding to the occurences of that event.

import { main, once, each } from 'effection';

await main(function*() {
  let socket = new WebSocket('ws://localhost:1234');

  for (let value of yield* each(on(socket, 'message'))) {
    console.log('message:', message.data);
    yield* each.next();
  }
});
  • PreviousStreams and Subscriptions
  • NextError Handling