Skip to content

Instantly share code, notes, and snippets.

@tonis2
Created June 4, 2019 06:49
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 tonis2/a689d9d55ceadc55a23158a102f9fb8e to your computer and use it in GitHub Desktop.
Save tonis2/a689d9d55ceadc55a23158a102f9fb8e to your computer and use it in GitHub Desktop.
Async websocket calls with ES6
const marker = () => {
return Math.random()
.toString(36)
.slice(2)
.padStart(10, "0")
}
export default class AsyncSocket {
constructor(url = null, config = {}) {
this.url = url
this.config = config
this.listeners = []
this.promises = []
this.server = null
this.waitFor = this.waitFor.bind(this)
this.resolveMessages = this.resolveMessages.bind(this)
this.sendAsync = this.sendAsync.bind(this)
}
listen(callback) {
if (!this.server) console.warn("No server found")
this.listeners.push(callback)
}
send(payload) {
let data = JSON.stringify(payload)
if (this.server.readyState === 1) this.server.send(data)
}
sendAsync(payload) {
if (!"postback" in payload) {
console.warn("Please provide postback for async calls")
return
}
return new Promise(resolve => {
this.server.send(JSON.stringify(payload))
this.promises.push({ type: "wait_for_postback", action: payload.postback.action, promise: resolve, marker: marker() })
})
}
waitFor(action) {
return new Promise(resolve => {
this.promises.push({ type: "wait_for_postback", action, promise: resolve, marker: marker() })
})
}
resolveMessages(message) {
const data = JSON.parse(message.data)
this.listeners.forEach(x => x(data))
this.promises.forEach(x => {
if (data.postback && data.postback.action === x.action && x.type === "wait_for_postback") {
x.promise(data)
this.promises = this.promises.filter(i => i.marker !== x.marker)
}
})
}
close() {
if (this.server) this.server.close()
}
async open() {
return new Promise((resolve, reject) => {
this.server = new WebSocket(this.url)
this.server.onmessage = message => this.resolveMessages(message)
this.server.onopen = () => resolve(this)
this.server.onerror = err => reject(err)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment