4 ms·
I really like Go channels, and I was looking for something like this in JS. One of the earlier implementations is this one, albeit not maintained anymore: http
by graup 3y ago
I really like Go channels, and I was looking for something like this in JS.
One of the earlier implementations is this one, albeit not maintained anymore: https://github.com/NodeGuy/channel https://github.com/NodeGuy/channel
I think I prefer its more concise API, e.g. for select (https://github.com/NodeGuy/channel/blob/main/API.md#examples https://github.com/NodeGuy/channel/blob/main/API.md#examples). ts-chan's API looks a bit too verbose to my taste.
Here's an example from ts-chan:
import {recv, Chan, Select} from 'ts-chan';
const ch1 = new Chan<number>();
const ch2 = new Chan<string>();
void sendsToCh1ThenEventuallyClosesIt();
void sendsToCh2();
const select = new Select([recv(ch1), recv(ch2)]);
for (let running = true; running;) {
const i = await select.wait();
switch (i) {
case 0: {
const v = select.recv(select.cases[i]);
if (v.done) {
running = false;
break;
}
console.log(`rounded value: ${Math.round(v.value)}`);
break;
}
case 1: {
const v = select.recv(select.cases[i]);
if (v.done) {
throw new Error('ch2 unexpectedly closed');
}
console.log(`uppercase string value: ${v.value.toUpperCase()}`);
break;
}
default:
throw new Error('unreachable');
}
}
I would consider rewriting the API to something like this:
import { receive, Channel, select } from 'ts-chan';
const ch1 = new Channel<number>();
const ch2 = new Channel<string>();
void sendsToCh1ThenEventuallyClosesIt();
void sendsToCh2();
for (let running = true; running;) {
switch(await select([receive(ch1), receive(ch2)])) {
case ch1: {
if (ch1.done) {
running = false;
break;
}
console.log(`rounded value: ${Math.round(ch1.value)}`);
}
case ch2: {
if (ch1.done) {
throw new Error('ch2 unexpectedly closed');
}
console.log(`uppercase string value: ${ch2.value.toUpperCase()}`);
break;
}
}
}
- joeycumines 3y agoI've been considering adding a `select` function, but I was concerned with the overhead of recreating the select case each time, and wanted to reserve it for a time once I've mulled over my options (I'm aiming to avoid making breaking changes, even though it's pre-v1). With receives, there's a value attached, and that presents some difficulties regarding typing (for TypeScript). You have given me an idea, however: I _might_ be able to wrangle together a mechanism that avoids making it a two-step deal (get the index, then resolve the type). It'd probably support only a subset of the functionality, though. It's on my list to add a simple example to the README using the `Chan` class. Communicating with a single channel (with or without abort support) is very simple, and I'm happy with the API for that.
- yunohn 3y agoIn addition to my other comment, I agree with the parent here. I appreciate the attempt to mirror golang’s naming, but it would be vastly more readable if you used Channel instead of Chan, etc.