kefirjs / kefir

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

Resetting a stream to the beginning #192

Closed indigo0086 closed 8 years ago

indigo0086 commented 8 years ago

I created a method that creates a I have a stream responding to the scroll event in this manner

const getScrollStream = (pages) =>  {
  const totalPages = 24
  return Kefir.fromEvents(sectionContainer, 'scroll')
    .debounce(250)
    .scan(prevPage => ++prevPage, 1)
    .skip(1)
    .takeWhile(page => page < totalPages)
}

var scrollStream = getScrollStream(24);
scrollStream.onValue(/* do something */)

my question is if I have a reference to this, stream is there a way to 'reset' the stream so that it starts from the beginning? Or would I just have to keep replacing scrollStream = getScrollStream(24) to reset it

niahoo commented 8 years ago

You can do this

const getScrollStream = (pages) =>  {
  const totalPages = 24
  return Kefir.fromEvents(sectionContainer, 'scroll')
    .debounce(250)
    .scan(prevPage => prevpage + 1, 1)
    .filter(page => page !== 1) // will skip all '1's
    // or .skip(1) // will only skip the 1st '1'
    .map(page => page % pages)
}

var scrollStream = getScrollStream(24);
scrollStream.onValue(/*
    Will receive 2, 3, 4, 5, 6 ... 22, 23, 1, 2, 3 infinitely
*/)

That beeing said, don't you wand to change the page up or down according to the direction of the scroll ?

rpominov commented 8 years ago

Good question! The answer is "no" unfortunately. All this operations debounce, scan, skip, takeWhile create a statetful stream. For example when we do foo.skip(1), we get a stream that have a piece of state — the count of how many events have came through. And there is no way to reset that count.

This is possible in other libraries like RxJs or Most though. They have notion of "cold" observables. So when we apply .skip(1) to a cold observable we create another cold observable that don't have any state. In a cold observable state is created per subscription. So if we subscribe twice to that observable, each subscription will have it's own count.