RxJS observables are async iterable (implemented using an unbounded buffer).
There's some good discussion of considerations and tradeoffs linked from that thread. Something to consider here.
// click-and-drag handler
element.addEventListener('mousedown', async () => {
for await (let { clientX, clientY } of element.on('mousemove').takeUntil(element.on('mouseup')) {
console.log('moved mouse to', clientX, clientY);
if (clientX > threshold) {
break; // triggers `return` handler from the async iterator, which automatically unsubscribes
}
}
console.log('mouse up or exceeded threshold');
});
is pretty cute.