Last active
September 1, 2021 13:23
-
-
Save dmitry-vsl/85a44ac66d4a266abd5295a6c540f592 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type='module'> | |
async function* fromEvent(el, event){ | |
let resolve | |
el.addEventListener(event, e => resolve(e)) | |
while(true){ | |
let promise = new Promise(_resolve => resolve = _resolve) | |
yield await promise | |
} | |
} | |
async function* startWith(asyncIterator, initialValue){ | |
yield initialValue | |
yield * asyncIterator | |
} | |
async function* reduce(asyncIterator, fn, initial){ | |
let current = initial | |
for await(let val of asyncIterator){ | |
current = fn(current, val) | |
yield current | |
} | |
} | |
function timeout(wait){ | |
let timeoutid | |
const promise = new Promise(resolve => { | |
timeoutid = setTimeout(resolve, wait) | |
}) | |
function cancel(){ | |
clearTimeout(timeoutid) | |
} | |
return [promise, cancel] | |
} | |
async function* debounce(asyncIterator, wait = 0){ | |
let value, next, cancel, timeoutPromise | |
let result = await asyncIterator.next() | |
while(true) { | |
if(result != null && result.done != null){ | |
if(!result.done){ | |
let value = result.value | |
next = asyncIterator.next() | |
if(cancel){ | |
cancel() | |
} | |
[timeoutPromise, cancel] = timeout(wait) | |
} else { | |
break | |
} | |
} else { | |
yield value | |
timeoutPromise = new Promise(resolve => {}) | |
let cancel = () => {} | |
} | |
result = await Promise.race([ | |
next, | |
timeoutPromise, | |
]) | |
} | |
} | |
async function main(){ | |
const clicks = fromEvent(document.getElementById('test'), 'click') | |
const debouncedClicks = debounce(clicks, 1000) | |
const clickCount = startWith( | |
reduce(debouncedClicks, (count, _) => count + 1, 0), | |
0, | |
) | |
for await(let count of clickCount){ | |
document.getElementById('count').innerText = count | |
} | |
} | |
window.addEventListener('load', main) | |
</script> | |
<body> | |
<button id='test'>Click me</button> | |
<span id='count'><span> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment