kefirjs / kefir

A Reactive Programming library for JavaScript
https://kefirjs.github.io/kefir/
MIT License
1.87k stars 97 forks source link

Should .take() unsubscribe from the source when it's done? #35

Closed myndzi closed 9 years ago

myndzi commented 9 years ago

Test code:

'use strict';

var Kefir = require('kefir');

var thing = Kefir.fromBinder(function (emitter) {
    console.log("subscribed");
    emitter.emit(1);

    var timer = setTimeout(function () {
        emitter.emit(2);
    }, 1000);

    return function () {
        console.log("unsubscribed");
        clearTimeout(timer);
    };
});

thing.take(1).onValue(function (val) {
    console.log(val);
});

The unsubscribe callback is never called

According to this issue, the subscriber to 'thing' should detach automatically after 1 item, so maybe this is a bug with fromBinder?

Interestingly, if I change it to take(2), the callback is called

myndzi commented 9 years ago

It appears to be the fault of the synchronous 'emit' -- if I make that asynchronous by wrapping it in process.nextTick(), it behaves as expected.

rpominov commented 9 years ago

Yes, there is a bug. Not easy to fix on the first look though. Funny that I found similar bug in Bacon recently https://github.com/baconjs/bacon.js/issues/523

The bug occurs when you truing to unsubscribe from a stream in response to the first value from it, and that first value is emitted synchronously.

Will think of how to fix this.

rpominov commented 9 years ago

The fix was actually pretty easy. Fixed in v0.5.2.

myndzi commented 9 years ago

Cool, thanks!

Back to trying to get pagination to work