Channels provide Go-style concurrent communication between tasks. They support buffering, backpressure strategies, and automatic cleanup when the scope is disposed.
Channels implement AsyncIterable, so you can use for await...of to consume values.
Buffered channels can hold multiple values before blocking:
// Create channel with buffer size 5const ch = s.channel<number>(5);// Send up to 5 items without blockingawait ch.send(1);await ch.send(2);await ch.send(3);await ch.send(4);await ch.send(5);// 6th send will block until someone receivesawait ch.send(6); // Blocks here
Control what happens when the channel buffer is full:
// Block sender until space is availableconst ch = s.channel<number>({ capacity: 10, backpressure: 'block'});// Send blocks when buffer is fullfor (let i = 0; i < 100; i++) { await ch.send(i); // Waits for consumer}
const ch = s.channel<string>(10);// Send a value (returns false if closed)const sent = await ch.send('hello');// Receive a value (returns undefined if closed and empty)const msg = await ch.receive();if (msg !== undefined) { console.log('Received:', msg);}// Close the channelch.close();// Check if closedif (ch.isClosed) { console.log('Channel is closed');}
Classic pattern with multiple producers and consumers:
await using s = scope();const jobs = s.channel<number>(100);const results = s.channel<number>(100);// Multiple producersfor (let i = 0; i < 3; i++) { s.task(async ({ signal }) => { for (let j = 0; j < 10; j++) { if (signal.aborted) break; await jobs.send(i * 10 + j); } });}// Multiple consumersfor (let i = 0; i < 5; i++) { s.task(async () => { for await (const job of jobs) { const result = await processJob(job); await results.send(result); } });}// Collectors.task(async () => { for await (const result of results) { console.log('Result:', result); }});// Close jobs channel when all producers are donePromise.all(producers).then(() => jobs.close());
await using s = scope({ timeout: 5000 });const ch = s.channel<string>(10);try { // If scope times out, send/receive are aborted await ch.send('message');} catch (err) { console.error('Channel operation cancelled');}// Channels are automatically closed when scope is disposed