Skip to content

Instantly share code, notes, and snippets.

@divs1210
Created September 13, 2023 09:09
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 divs1210/a6c0e2a4bff9ed8a0dc9a750b0714d14 to your computer and use it in GitHub Desktop.
Save divs1210/a6c0e2a4bff9ed8a0dc9a750b0714d14 to your computer and use it in GitHub Desktop.
Go-style CSP in JavaScript
const CLOSED = Symbol('chan-closed');
const StackGC = async () => null;
class Chan {
constructor(size) {
this.q = [];
this.size = size || 1;
this.isClosed = false;
}
async put(x) {
if (this.isClosed)
return false;
else if (this.q.length == this.size) {
await StackGC();
return await this.put(x);
} else if (x === CLOSED) {
this.isClosed = true;
return true;
}else {
this.q.push(x);
return true;
}
}
async take() {
if (this.isClosed && this.q.length === 0)
return CLOSED;
else if (this.q.length === 0) {
await StackGC();
return await this.take();
} else
return this.q.shift();
}
async close() {
this.put(CLOSED);
}
}
async function go(f) {
return await f();
}
// Tests
// =====
function test1() {
let ch = new Chan();
go(async () => {
console.log('got:', await ch.take());
});
ch.put('hi!');
}
function test2() {
// takes and prints values from channel
// till it is closed
async function printAll(ch) {
while(true) {
let x = await ch.take();
if (x === CLOSED)
break;
console.log(x);
}
}
let ch = new Chan();
ch.put(0);
ch.put(1);
ch.put(2);
ch.close();
ch.put(3);
printAll(ch);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment