Skip to content

Instantly share code, notes, and snippets.

@benjamingr
Created December 8, 2020 18:40
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 benjamingr/b2c43f25d9a30fd0399f3c9e1bb676dd to your computer and use it in GitHub Desktop.
Save benjamingr/b2c43f25d9a30fd0399f3c9e1bb676dd to your computer and use it in GitHub Desktop.
/*
Makes a channel that buffers up to n items
*/
function chan(n) {
const data = []; // data not yet read
const readersBacklog = []; // readers waiting for data
const writersBacklog = []; // writers waiting for data
let disposed = false;
// TODO(Benjamin) - disposing
return {
async read() {
if (data.length === n) {
// data is full
const nextWaitingWrite = writersBacklog.shift();
nextWaitingWrite();
}
if (data.length > 0) {
return data.shift();
}
return new Promise(resolve => readersBacklog.push(resolve));
},
async write(datum) {
if (data.length === 0) {
const resolve = readersBacklog.shift();
resolve(datum);
return;
}
if (data.length < n) {
data.push(datum);
return;
}
return new Promise(resolve => {
writersBacklog.push(() => {
data.push(datum);
resolve();
});
});
},
async *[Symbol.asyncIterator]() {
while(!disposed) yield await this.read();
},
};
}
/*
this impementation is very slow (for the arrays and queue and closure)
but it just demonstrates how
*/
{
// Example with 1 concurrency, uncomment to see
// const c = chan(1); // only one at once
// let i = 0;
// (async () => {
// setInterval(() => c.write('hello world!', i++), 200);
// for await(const data of c) {
// console.log('got data', data);
// }
// })();
}
{
// example with two readers
const c = chan(2);
let i = 0;
setInterval(() => c.write('hello world!', i++), 200);
(async () => {
for await(const data of c) {
console.log('got data first channel', data);
}
})();
(async () => {
for await(const data of c) {
console.log('got data second channel', data);
}
})();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment