Last active
June 9, 2020 19:46
-
-
Save Sceat/465b44a8e6c7e05dc8c173e809c08a12 to your computer and use it in GitHub Desktop.
EventIterator raw JS file translated from https://github.com/rolftimmermans/event-iterator
This file contains 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
const noop = () => {} | |
export default class EventIterator { | |
#listen | |
#options | |
constructor(listen, options) { | |
this.#listen = listen | |
this.#options = { | |
highWaterMark: 100, | |
...options, | |
} | |
Object.freeze(this) | |
} | |
[Symbol.asyncIterator]() { | |
let pullQueue = [] | |
const pushQueue = [] | |
const listen = this.#listen | |
let remove = noop | |
let finaliser = 0 | |
const push = value => { | |
const resolution = { | |
value, | |
done: false, | |
} | |
if (pullQueue.length) | |
pullQueue.shift()?.resolve(resolution) | |
else { | |
pushQueue.push(Promise.resolve(resolution)) | |
const { highWaterMark } = this.#options | |
if ( | |
highWaterMark !== undefined | |
&& pushQueue.length >= highWaterMark | |
) | |
console.log(`EventIterator queue reached ${ pushQueue.length } items`) | |
} | |
} | |
const stop = () => { | |
Promise.resolve().then(() => { | |
remove() | |
finaliser = { | |
value: undefined, | |
done : true, | |
} | |
if (pullQueue.length) { | |
for (const placeholder of pullQueue) | |
placeholder.resolve(finaliser) | |
pullQueue = [] | |
} else pushQueue.push(Promise.resolve(finaliser)) | |
}) | |
} | |
const fail = error => { | |
Promise.resolve().then(() => { | |
remove() | |
if (pullQueue.length) { | |
for (const placeholder of pullQueue) | |
placeholder.reject(error) | |
pullQueue = [] | |
} else { | |
const rejection = Promise.reject(error) | |
// Attach error handler | |
// to avoid leaking an unhandled promise rejection. | |
rejection.catch(() => {}) | |
pushQueue.push(rejection) | |
} | |
}) | |
} | |
remove | |
= listen({ | |
push, | |
stop, | |
fail, | |
}) || remove | |
return { | |
async next() { | |
if (finaliser) return finaliser | |
else if (pushQueue.length) return pushQueue.shift() | |
return new Promise((resolve, reject) => { | |
pullQueue.push({ | |
resolve, | |
reject, | |
}) | |
}) | |
}, | |
async return() { | |
remove() | |
finaliser = { | |
value: undefined, | |
done : true, | |
} | |
return finaliser | |
}, | |
} | |
} | |
} |
This file contains 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
{ | |
"name": "event-iterator", | |
"version": "0.1.0", | |
"type": "module", | |
"main": "EventIterator.js" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment