import { chan } from "https://deno.land/x/ayonli_jsext@v0.9.72/esm/workerd/index.js";
Inspired by Golang, cerates a Channel that can be used to transfer data across routines.
If capacity
is not set, a non-buffered channel will be created. For a
non-buffered channel, the sender and receiver must be present at the same
time (theoretically), otherwise, the channel will block (non-IO aspect).
If capacity
is set, a buffered channel will be created. For a buffered
channel, data will be queued in the buffer first and then consumed by the
receiver in FIFO order. Once the buffer size reaches the capacity limit, no
more data will be sent unless there is new space available.
It is possible to set the capacity
to Infinity
to allow the channel to
never block and behave like a message queue.
Unlike EventEmitter
or EventTarget
, Channel
guarantees the data will
always be delivered, even if there is no receiver at the moment.
Also, unlike Golang, await channel.recv()
does not prevent the program from
exiting.
Channels can be used to send and receive streaming data between main thread
and worker threads wrapped by parallel()
, but once used that way,
channel.close()
must be explicitly called in order to release the channel
for garbage collection.
Examples
Example 1
Example 1
// non-buffered
import chan from "@ayonli/jsext/chan";
const channel = chan<number>();
(async () => {
await channel.send(123);
})();
const num = await channel.recv();
console.log(num); // 123
// output:
// 123
Example 2
Example 2
// buffered
import chan from "@ayonli/jsext/chan";
const channel = chan<number>(3);
await channel.send(123);
await channel.send(456);
await channel.send(789);
const num1 = await channel.recv();
const num2 = await channel.recv();
const num3 = await channel.recv();
console.log(num1); // 123
console.log(num2); // 456
console.log(num3); // 789
Example 3
Example 3
// iterable
import chan from "@ayonli/jsext/chan";
import { range } from "@ayonli/jsext/number";
const channel = chan<number>();
(async () => {
for (const num of range(1, 5)) {
await channel.send(num);
}
channel.close();
})();
for await (const num of channel) {
console.log(num);
}
// output:
// 1
// 2
// 3
// 4
// 5