Skip to content

Instantly share code, notes, and snippets.

@paruljain
Last active June 5, 2019 23:16
Show Gist options
  • Save paruljain/949badfda2d163faa15d773a9f52ede9 to your computer and use it in GitHub Desktop.
Save paruljain/949badfda2d163faa15d773a9f52ede9 to your computer and use it in GitHub Desktop.
'use strict'
class Channel {
constructor(buffer) {
if (!buffer) this.buffer = 1
else this.buffer = buffer
this.data = []
this.putPromiseResolve = null
this.getPromiseResolve = null
this.putData = null
this.closed = false
}
put(item) {
return new Promise((resolve, reject) => {
if (this.closed) reject(new Error('Channel is closed'))
else if (this.data.length < this.buffer) {
this.data.push(item)
resolve()
if (this.getPromiseResolve) {
const r = this.getPromiseResolve
this.getPromiseResolve = null
r(this.data.shift())
}
}
else {
this.putPromiseResolve = resolve
this.putData = item
}
})
}
get() {
return new Promise((resolve, reject) => {
if (this.data.length) {
resolve(this.data.shift())
if (this.putPromiseResolve) {
this.data.push(this.putData)
const r = this.putPromiseResolve
this.putPromiseResolve = null
r()
}
}
else if (this.closed) {
resolve()
}
else {
this.getPromiseResolve = resolve
}
})
}
close() {
this.closed = true
if (!this.data.length && this.getPromiseResolve) {
const r = this.getPromiseResolve
this.getPromiseResolve = null
r()
}
}
}
const c = new Channel()
async function getter() {
while(true) {
const r = await c.get()
if (!r) {
console.log('Channel is closed')
break
}
console.log(r)
}
}
async function putter() {
await c.put('hello world 1')
await c.put('hello world 2')
await c.put('hello world 3')
c.close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment