Skip to content

Instantly share code, notes, and snippets.

@yskszk63
Created February 6, 2018 13:56
Show Gist options
  • Save yskszk63/bc6dd7cb9cc4e87225a919c288a900e1 to your computer and use it in GitHub Desktop.
Save yskszk63/bc6dd7cb9cc4e87225a919c288a900e1 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Async Iterator</title>
</head>
<body>
<pre></pre>
<script src="script.js"></script>
</body>
</html>
<!-- vim:set sw=2 ts=2: -->
async function main() {
for await (const event of iterEvents(document, 'click')) {
log(event, event.target);
if (event.target.matches('pre')) {
throw new Error("pre clicked");
}
}
}
function log(...s) {
document.querySelector('pre')
.appendChild(new Text(s.map(String).join(' ') + '\n'));
}
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
}
async function* iterEvents(element, type) {
let signal = null;
const results = [];
let done = false;
function handler(event) {
if (signal) {
signal.resolve();
}
results.push(event);
}
log("begin");
element.addEventListener(type, handler);
try {
while (!done) {
if (!results.length) {
signal = new Deferred();
await signal.promise;
signal = null;
} else {
yield results.shift();
}
}
} finally {
element.removeEventListener(type, handler);
log("end");
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment