Requiring next_fn to be available at listen() time means you can't pass
subscriptions around, and it is often hard to create next_fn, since it
usually needs to capture 'this', while this also points to the subscription
itself, creating a chicken and egg problem.
Fix by separating the registration process into two steps: listen() creates
the subscription, and start() accepts the next callback and starts processing
events.
The future/promise pair is for single-shot use only, which makes it
less useful for repetitive processing.
Add a stream/subscription abstraction, where a stream can produce data
which is repetitively consumed by the subscription. End-or-stream (or
error condition) is provided by a future.
Inspired by Dart's Stream class.