To "streamify" a map of callbacks
junjchen opened this issue · comments
Hi guys,
I was doing a facade on a legacy API where a map of callback is passed in as an arg like:
const myStupidListeners = {
aHappened: e => {},
bHappened: e => {},
cHappened: e => {}
}
invokeLegacyAPI("start", myStupidListeners)
I was trying to wrap this API to multiple event streams using bacon, so for each xHappened
callback, an event stream shall be created.
But however I just can't spin my head around how to "streamify" those callbacks using factory functions provided by Bacon, at best I'm thinking of kicking start a Bus
for each callbacks and pushing events to that bus in those callbacks.
Am I missing somehing form the doc and is there a better way to do this?
Probably a Bus is the easiest solution. There are other options but since you have three callbacks you want to pass simultaneously it's a bit trickier.
const onA = new Bacon.Bus();
const onB = new Bacon.Bus();
const onC = new Bacon.Bus();
const myStupidListeners = {
aHappened: ev => onA.push(ev),
bHappened: ev => onB.push(ev),
cHappened: ev => onC.push(ev),
};
invokeLegacyAPI("start", myStupidListeners);
If you need help with the finer points, like unsubscribing or signalling the stream done event you'll have to provide some more details on the legacy API.
Optionally you can
allEvents = B.fromBinder(function(sink) { invokeLegacyAPI({a: sink, b: sink, c: sink}) })
This ways you'll get all events into one stream. Then you need to split it into three by applying different filters. Note that you could also can tag your data like
allEvents = B.fromBinder(function(sink) { invokeLegacyAPI({
a: function(a) { sink ({a: a}) },
b: function(b) { sink ({b: b}) },
c: function(b) { sink ({c: c}) }
})})
So that you allEvents
stream will output stuff like
{a: "value from event a" }
{c: "something else from c"}
The Bus approach seems more approachable to me.
@philipnilsson @raimohanska Thank you for your great input on the topic.
The only concern to exploit Bacon.Bus
from me is that it enables user to be a little over-powered to push events to the bus.
I have not thought of using fromBinder
before and it seems to be a decent approach as well.
Another solution pops into my mind just now was to use EventEmitter
and Bacon.fromEvent
, something like
const emitter = new EventEmitter()
const myStupidListeners = {
aHappened: e => emitter.emit('a', e),
bHappened: e => emitter.emit('b', e),
cHappened: e => emitter.emit('c', e)
}
// then from events
const onA = Bacon.fromEvent(emitter, 'a');
const onB = Bacon.fromEvent(emitter, 'b');
const onC = Bacon.fromEvent(emitter, 'c');
Haven't tried out yet but looks as well approachable.
@junjchen Did this solution work out for you? Can we close this issue?