Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

throttleWhen #78

Merged
merged 3 commits into from
Mar 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions module/batchwhen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# flyd-batchwhen

Batches values from the second stream (sA) based on the the first stream (sBool)
as a control signal. When sBool is false, sA are passed through as a single
element list. When sBool is true, then values feom sA are batched into a list,
and the batch is emitted when sBool returns to false. This function is convenient
for throttling user inputs.

# Usage

```js
var action$ = flyd.stream()
var throttle$ = flyd.stream(false)
var batchedAction$ = flyd.batchWhen(throttle$, action$)

action$(1)
// batchedAction$ => [1]
action$(2)
// batchedAction$ => [2]
throttle$(true)
action$(3)
action$(4)
throttle$(false)
// batchedAction$ => [3, 4]
throttle$(true)
throttle$(false)
```
62 changes: 62 additions & 0 deletions module/batchwhen/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
var flyd = require('../../lib');
var dropRepeats = require('../droprepeats').dropRepeats;
var contains = require('ramda/src/contains');

// Stream bool -> Stream a -> Stream a
module.exports = flyd.curryN(2, function(sBool, sA) {
var batch = [];

var ns = flyd.combine(function(sBool, sA, self, changed) {

var sBoolChanged = contains(sBool, changed);
var sAChanged = contains(sA, changed);


if (sA() !== undefined) {
// if A is undefined then we dont batch anything
if (sBoolChanged) {
if (sAChanged) {
if (sBool()) {
// if Bool and A change and were batching then
// push to the batch
batch.push(sA());
} else {
// if Bool and A change and we're not batching
// anymore, then push the batch
batch.push(sA());
self(batch);
batch = [];
}
} else {
if (!sBool()) {
// if Bool changed but A didnt then push the batch
// if there were any batching
if (batch.length > 0) {
self(batch);
batch = [];
}
}
}
} else if (sAChanged) {
if (sBool()) {
// if we're batching then push to the batch
batch.push(sA());
} else {
// otherwise send it alone
self([sA()]);
}
} else {
// when we just initialize
// if theres a value in A
if (sBool()) {
batch.push(sA());
} else {
self([sA()]);
}
}
}

}, [dropRepeats(sBool), sA]);

return ns;
});
86 changes: 86 additions & 0 deletions module/batchwhen/test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
var assert = require('assert');
var flyd = require('../../../lib');
var stream = flyd.stream;

var batchWhen = require('../index.js');

describe('batchWhen', function() {
it('batches the second stream with the first stream, initally false', function() {
var result = [];
var s = stream(1);
var b = stream(false);
var k = batchWhen(b, s);
flyd.map(function(v) {
result.push(v);
}, k);
s(2);
b(true);
s(3);
s(4);
b(false);
b(true);
b(false);
s(5);
assert.deepEqual(result, [[1], [2], [3, 4], [5]]);
});

it('batches the second stream with the first stream, initially true', function() {
var result = [];
var s = stream(1);
var b = stream(true);
var k = batchWhen(b, s);
flyd.map(function(v) {
result.push(v);
}, k);
s(2);
b(false);
s(3);
s(4);
b(true);
b(false);
b(true);
b(false);
s(5);
assert.deepEqual(result, [[1, 2], [3], [4], [5]]);
});

it('batches the second stream with the first stream, initially true, with no value', function() {
var result = [];
var s = stream();
var b = stream(true);
var k = batchWhen(b, s);
flyd.map(function(v) {
result.push(v);
}, k);
s(2);
s(3);
b(false);
s(4);
b(true);
b(false);
b(true);
b(false);
s(5);
assert.deepEqual(result, [[2, 3], [4], [5]]);
});

it('batches the second stream with the first stream, initially false, with no value', function() {
var result = [];
var s = stream();
var b = stream(false);
var k = batchWhen(b, s);
flyd.map(function(v) {
result.push(v);
}, k);
s(2);
b(true);
s(3);
s(4);
b(false);
b(true);
b(false);
s(5);
assert.deepEqual(result, [[2], [3, 4], [5]]);
});

});