Manipulating Bacon.js Event Streams

Federico Knüssel
Dec 26, 2016 · 12 min read

Immutability

Map

const numbers = [1, 2, 3];
const doubles = numbers.map((number) => 2 * number);
http://rxmarbles.com/#map
const numbersStream = Bacon.sequentially(300, [1, 2, 3]);
const doublesStream = numbersStream.map((value) => 2 * value);
const ones = clicks.map(1);

Filter

http://rxmarbles.com/#filter
const numbersStream = Bacon
.sequentially(300, [2, 30, 22, 5, 60, 1]);
const filteredStream = numbersStream
.filter((value) => value > 20)
.log('filteredStream');
observable.filter(false);
productsStream.filter('.isAvailable');

Fold or Reduce

const numbers = [1, 2, 3, 4, 5];
const sum = numbers
.reduce((accumulator, value) => accumulator + value, 0);
const numbersStream = Bacon
.sequentially(300, [1, 2, 3, 4, 5]);
const foldStream = numbersStream
.fold(0, (accumulator, value) => accumulator + value)
.log('foldStream');

Scan

http://rxmarbles.com/#scan
const numbersStream = Bacon
.sequentially(300, [1, 2, 3, 4, 5]);
const scanStream = numbersStream
.scan(0, (accumulator, value) => accumulator + value)
.log('scanStream');

Take

http://rxmarbles.com/#take
const numbersStream = Bacon
.sequentially(300, [1, 2, 3, 4]);
// This will emit the first two values and end
const takeStream = numbersStream
.take(2)
.log('takeStream');
// This will immediately end
const takeNoneStream = numbersStream
.take(0) // might as well be a negative number
.log('takeNone');
// This will emit the first 4 values of the source stream and end
const takeMoreThanFourStream = numbersStream
.take(20)
.log('takeMoreThanFourStream');
const numbers = [1, 2, 3, 4];
const takeFirstThree = numbers.filter((value, index) => index <= 2);

Skip

http://rxmarbles.com/#skip
const numbersStream = Bacon
.sequentially(100, [1, 2, 3, 4]);
// This will skip the first two values and then end
const skipStream = numbersStream
.skip(2)
.log('skipStream');
const skipNone = numbersStream
.skip(0) // might as well be a negative number
.log('skipNoneStream');
// Will end but not immediately, rather after the
// source stream has emitted all of its four values
const skipMoreThanFourStream = numbersStream
.skip(20)
.log('skipMoreThanFourStream');

First

http://rxmarbles.com/#first
const numbersStream = Bacon
.sequentially(100, [1, 2, 3, 4]);
const firstValueStream = Bacon
.first()
.log('firstValueStream');

Last

http://rxmarbles.com/#last
const numbersStream = Bacon
.sequentially(100, [1, 2, 3, 4]);
const lastValueStream = Bacon
.last()
.log('lastValueStream');

Take While

const numbersStream = Bacon
.sequentially(300, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
const takeWhileStream = numbersStream
.takeWhile((value) => value * value < 30)
.log('takeWhileStream');

Take Until

http://rxmarbles.com/#takeUntil
const numbersStream = Bacon
.sequentially(300, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
const zerosStream = Bacon
.sequentially(1500, [0, 0]);
// Take values from the numbers stream until an event
// gets pushed down the zeros stream
const takeUntilStream = numbersStream
.takeUntil(zerosStream)
.log('takeUntilStream');
// Bacon.never emits no values. However, takeUntilNever
// emits all values in the source stream
const takeUntilNeverStream = numbersStream
.takeUntil(Bacon.never())
.log('takeUntilNeverStream');

Delay

http://rxmarbles.com/#delay
const numbersStream = Bacon
.sequentially(300, [1, 2, 3]);
const delayStream = numbersStream
.delay(900)
.log('delayStream');
const noDelayStream = numbersStream
.delay(0) // might as well be a negative number
.log('noDelayStream');

Debounce

https://css-tricks.com/debouncing-throttling-explained-examples/
const button = document.getElementById('btn');const clicksStream = Bacon
.fromEvent(button, 'click')
.map('This is a click event');
const debouncedStream = clicksStream
.debounce(1000)
.log('debouncedStream');
http://rxmarbles.com/#debounce
const inputStream = Bacon
.fromEvent(document.querySelector('#input'), 'keydown')
.debounce(300) // limit the rate of queries
.map((event) => event.target.value); // get text value from event

Debounce Immediate

https://css-tricks.com/debouncing-throttling-explained-examples/

Throttle

Not

const booleansStream = Bacon
.sequentially(300, [true, false, true]);
const invertedBooleansStream = booleansStream
.not()
.log('invertedBooleansStream');
const booleansStream = Bacon
.sequentially(300, ['bacon', 1, 0, null, '', {}, []]);

Making infinite streams end

Extra resources and complementary readings

Federico Knüssel

Written by

Front End Developer 👨‍💻 🇦🇺

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade