Last active
March 7, 2018 03:39
-
-
Save zeusdeux/c56359801313f30d50b1952bfad26182 to your computer and use it in GitHub Desktop.
Async generators as wrappers around event emitters
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
let socket = new WebSocket('wss://echo.websocket.org') | |
async function main(socket) { | |
for await (let {value, done} of getDataFromWebSocket(socket)) { | |
if (!done) console.log('Data:', value) | |
else console.log('WebSocket is closed.') | |
} | |
return 'Done running the main fn!' | |
} // hit return/enter | |
// if you're running this in the dev console run this first and hit return/enter | |
await main(socket) | |
// since we are using the demo hosted echo websocket, it echoes what we send it | |
// so to receive a value, we first send it a value | |
// select all upto socket.send(4) and hit enter and you'll see the Data: <number> | |
// as ouput | |
socket.send(1) | |
socket.send(2) | |
socket.send(3) | |
socket.send(4) | |
// after seeing the output of the send commands type this and hit enter | |
// you'll see WebSocket is closed. printed followed by the promise | |
// return by the async main() fn resolving to the return value of | |
// main which is 'Done running the main fn!' | |
// This tells us that the loop in main was exited and main returned as well | |
socket.close() |
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
async function* getDataFromWebSocket(sock) { | |
// from https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants | |
const READY_STATE_MAP = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'] | |
// our custom data object that the promise for a websocket message resolves to | |
// it has value with raw event data and a done property which is set to true | |
// when the WebSocket connection has been closed | |
const makeDataObj = evt => ({ | |
value: evt.data, | |
done: READY_STATE_MAP[evt.target.readyState] === 'CLOSED' | |
}) | |
// hoisted out promise along with the resolve and reject fns for that promise | |
let prom, resolve, reject | |
// true iff the WebSocket connection has been closed | |
let done = false | |
sock.onmessage = e => resolve(makeDataObj(e)) | |
sock.onclose = e => { | |
done = true | |
resolve(makeDataObj(e)) | |
} | |
while (!done) { | |
prom = new Promise((res, rej) => { | |
resolve = res | |
reject = rej | |
}) | |
yield prom | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment