-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasync_iterable_events.js
54 lines (53 loc) · 1.24 KB
/
async_iterable_events.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"use strict"
EventTarget.prototype.on = function(events = "" || [], options = {}, callback) {
let target = this
if(typeof(options) == "function") {
callback = options
options = {}
}
if(typeof(events) == "string") {
events = [ events ]
}
let resolver, iterator
let resolvers = [], results = []
let removed = false
function listener(value) {
if(resolver) {
resolver(value)
}
if(resolvers.length) {
resolvers.shift()({ done: false, value })
} else {
results.push(value)
}
if(options.once) {
iterator.return()
}
if(callback) {
callback.call(target, value)
} }
for(let event of events) {
target.addEventListener(event, listener, options)
}
return(Object.assign(new Promise(function(resolve) {
resolver = resolve
}), iterator = {
async next() {
if(results.length) {
return({ done: false, value: results.shift() })
} else if(removed) {
return({ done: true, value: undefined })
} else {
return(new Promise(function(resolve) {
resolvers.push(resolve)
})) } },
async return() {
removed = true
for(let event of events) {
target.removeEventListener(event, listener, options)
}
return({ done: true, value: undefined })
},
[Symbol.asyncIterator]() {
return(this)
} })) }