Remeber: each broadcast return a cancel function
let createTimeout = (time) => (listener) => { let id = setTimeout(listener, time) return () => { clearTimeout(id) } } let addListener = (selector) => (eventType) => (listener) => { let element = document.querySelector(selector) element.addEventListener(eventType, listener) return () => { element.removeEventListener(eventType, listener) } } let createInterval = (time) => (listener) => { let id = setInterval(listener, time) return () => { clearInterval(id) } } let addButtonListener = addListener('#button') let addButtonClickListener = addButtonListener('click') let oneSecond = createInterval(1000) //broadcaster = function that accepts a listener let merge = (broadcaster1, broadcaster2) => (listener) => { let cancel1 = broadcaster1(listener) let cancel2 = broadcaster2(listener) return () => { cancel1() cancel2() } } let clickOrTick = merge(addButtonClickListener, oneSecond) let cancelClickOrTick = clickOrTick(() => { console.log('click or tick') }) cancelClickOrTick()
- because both broadcasters (
addButtonClickListener
&oneSecond
) expects a listener, we are able to create a wrapper function that accepts a listener too and explicitly pass it to both broadcasters, which in this example we call itmerge
-
and also we can follow the same pattern as before, because we control the broadcasters we are getting as parameters in
merge
, so we can return another function that cancels both of them - For the sake of comparison and help with readability, here's a representation of the functions both using ES6 syntax and ES5 syntax (using the function keyword)
// Merge two different text inputs const mergeInputs = (input1, input2) => listener => { let result = '' const cancel1 = input1((e) => result += e.target.value) const cancel2 = input2((e) => result += e.target.value) listener(result) return () => { cancel1(); cancel2();} }