Skip to content

Instantly share code, notes, and snippets.

@Gozala
Last active February 9, 2018 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gozala/86f0f8baf9c0a197e33b3092ddd0f19b to your computer and use it in GitHub Desktop.
Save Gozala/86f0f8baf9c0a197e33b3092ddd0f19b to your computer and use it in GitHub Desktop.
🕺Async generators are really cool! 🕺
// https://github.com/tc39/proposal-async-iteration
var Read = class Read {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}
return(value) {
this.value = value
this.done = false
this.resolve(this)
}
cancel() {
this.value = undefined
this.done = true
}
throw(error) {
this.error = error
this.reject(error)
}
}
var On = class On {
constructor(type, target, capture=false) {
this.type = type
this.target = target
this.status = 'ready'
this.readQueue = []
}
[Symbol.asyncIterator]() {
return this
}
next() {
switch (this.status) {
case "ready": {
const read = new Read()
this.readQueue.push(read)
this.target.addEventListener(this.type, this, this.capture)
this.status = 'subscribed'
return read.promise
}
case "subscribed": {
const read = new Read()
this.readQueue.push(read)
return read.promise
}
case "unsubscribed": {
return {done:true, value:null}
}
}
}
handleEvent(event) {
const read = this.readQueue.shift()
if (read) {
read.return(event)
}
}
return() {
this.status = "unsubscribed"
this.target.removeEventListener(this.type, this, this.capture)
for (const read of this.readQueue.splice(0)) {
read.cancel()
}
}
throw(error) {
this.status = "unsubscribed"
this.target.removeEventListener(this.type, this.target, this.capture)
for (const read of this.readQueue.splice(0)) {
read.throw(error)
}
}
}
async function log(xs) {
for await (let x of xs) {
console.log(x)
}
}
log(new On('mousemove', document.body))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment