paldepind / flyd

The minimalistic but powerful, modular, functional reactive programming library in JavaScript.
MIT License
1.56k stars 84 forks source link

Throttle module #85

Open jimf opened 8 years ago

jimf commented 8 years ago

Howdy. I'd be interested in adding a throttle module, but had a few questions before doing so. As for implementation, I was thinking something along the lines of:

var flyd = require('flyd');
var _throttle = require('lodash.throttle');

module.exports = flyd.curryN(2, throttle(ms, s) {
  return flyd.combine(_throttle(function(s, self) {
    self(s());
  }, ms), [s]);
});

My questions:

  1. Can this more or less already be achieved with what's here, and I'm just missing it?
  2. I'm fairly new to this reactive stuff. Is this implementation more or less analogous with throttle from RxJS et al (of course, sans schedulers and what not)?
  3. This would add a dependency on lodash.throttle. As such, do you have a preference on this module living here vs a dedicated repo?
paldepind commented 8 years ago

Is what you're requesting similar to #78 by @ccorcos?

jimf commented 8 years ago

No, it'd be just like the throttle from RxJS or Bacon: basically, take a stream, and return a new stream that throttles results from the stream by a given delay. Useful for scroll events and such, that are far more noisy than is typically needed.

Example:

var throttledScrollStream = flyd.throttle(250, scrollStream);
c-dante commented 8 years ago

The only suspect feeling I have is this is strictly using an external library wrapping a combine -- I understand wanting to present modules that provide functionality like Kefir or Bacon or Rx's APIs do (sampleBy, debounce, throttle, skipWhile, bufferWhile, ...), but does it make sense to have modules like this one as-is?

garkin commented 7 years ago

Also debounce, delay. Those things are massively useful for tuning asynchronous flows.

janat08 commented 5 years ago

Couldn't find delay, and debounce won't do anything at all while stuff is happening.

nordfjord commented 5 years ago

Both are fairly easily implemented. Feel free to take these and use them.

export const debounce = ms => s => {
  var timeout
  return flyd.combine((s,self)=> {
    clearTimeout(timeout)
    timeout = setTimeout(()=> self(s.val), ms)
  }, [s])
}

export const delay = ms => s => {
  return flyd.combine((s, self)=> {
    setTimeout(()=> self(s.val), ms)
  }, [s])
}

Usage:

const s = stream()

const d = s.pipe(delay(2))

s(1)

// s: 1---
// d: --1-

const s = stream()
const d = s.pipe(debounce(2))
s(1)
s(2)

// s: 12---
// d: ----2
janat08 commented 5 years ago

I meant something that starts immediately: s: 1111 d: 1-1-