const compose = (...fns) => (...args) => fns.reduceRight((res, fn) => [fn.call(null, ...res)], args)[0]; const input = document.getElementById("nameInput"); const log = value => { console.log(value); }; const logValue = broadcaster => listener => { broadcaster(event => { listener(event.target.value); }); }; const inputEvent = listener => input.addEventListener("input", listener); const debounce = time => broadcaster => { let timer = null; return listener => { broadcaster(event => { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { listener(event); }, time); }); }; }; const debounceInputValue = compose( logValue, debounce(500) ); debounceInputValue(inputEvent)(log);