DOM EventStreams (take two on Streams): Request for feedback

Jason Orendorff jason.orendorff at gmail.com
Thu Apr 18 16:26:09 PDT 2013


(narrowing to the part that seems most productive)

On Wed, Apr 17, 2013 at 9:11 PM, Tab Atkins Jr. wrote:
> On Wed, Apr 17, 2013 at 5:50 PM, Jason Orendorff wrote:
>> Bacon offers two equivalent ways of unsubscribing.
>>
>> 1. Bacon's equivalent of the StreamInit callback returns an
>> unsubscribe function. Each subscriber therefore gets its very own
>> unsubscribe callback.
>
> Ah, that's an interesting idea.
>
> I'm unsure how each subscriber gets its own unsubscribe callback.  The
> init callback is only called once, and so returns only the single
> value, right?
>
> Or is the subscribe callback called every time someone starts
> listening, so the stream can potentially act different to different
> listeners?  That seems like it would be hard to make compatible with a
> multi-listener approach.

Right. It's not quite per-listener; as in your design, the EventStream
class copes with multiple simultaneous listeners.

But when the number of listeners on an EventStream goes from 0 to 1,
it calls the subscribe hook; when it goes from 1 to 0, it calls the
unsubscribe hook.

This is because Bacon turns off all the taps when no one's listening.
Futures are not like that.

Example:

    var clock = Bacon.interval(100, "tick");
    clock.take(5).log();
    setTimeout(() => clock.take(5).log(), 2000);

The call to .log() on line 2 causes .take(5) to have a consumer, so
clock's subscribe hook is called. We log some events; 500 msec later,
.take(5) receives its fifth event, so it's all done. It unsubscribes
itself and floats away.

clock goes to 0 consumers, so it calls the unsubscribe hook.

At 2000 msec, clock once again has a downstream consumer, so its
subscribe hook is called a second time.

>> 2. Additionally, Bacon's equivalent of the EventStreamResolver.push()
>> method can return a special value (Bacon.noMore) that means
>> "unsubscribe me".
>
> That just kicks out all the listeners to the stream?  Or does it end
> the stream?  Or do you mean something else, given that you use the
> pronoun "me", which implies it's the *listener* with somehow sends the
> signal?  If the latter, you're confused about the role of a stream
> resolver.

Bacon's equivalent of EventStreamResolver.push() returns Bacon.noMore
when it finds that the number of listeners has gone to 0.

This is indeed usually caused by the last listener unsubscribing by
returning Bacon.noMore; and this is the point where I think it'll be
quickest to cut short the discussion and just read some Bacon source
code.

This is called for every event:
https://github.com/raimohanska/bacon.js/blob/6318160839d76ed4ce4eceeefe5d0d78b8e45403/src/Bacon.coffee#L777

-j


More information about the es-discuss mailing list