Non Blocking Channel Operations in TypeScript
Basic sends and receives on channels are blocking in many concurrent programming models. However, we can implement non-blocking operations using a similar pattern in TypeScript with Promises and async/await.
async function main() {
const messages = new Promise<string>((resolve) => {
// Simulating a channel
});
const signals = new Promise<boolean>((resolve) => {
// Simulating a channel
});
// Here's a non-blocking receive. If a value is
// available on `messages` then it will be logged.
// If not, it will immediately log "no message received".
try {
const msg = await Promise.race([
messages,
Promise.reject("no message")
]);
console.log("received message", msg);
} catch (error) {
console.log("no message received");
}
// A non-blocking send works similarly. Here `msg`
// cannot be sent to the `messages` promise, because
// it has no resolver. Therefore, the catch block is executed.
const msg = "hi";
try {
await Promise.race([
new Promise<void>((resolve) => {
// Simulating sending a message
resolve();
}),
Promise.reject("no send")
]);
console.log("sent message", msg);
} catch (error) {
console.log("no message sent");
}
// We can use multiple promises with `Promise.race`
// to implement a multi-way non-blocking select.
// Here we attempt non-blocking receives on both
// `messages` and `signals`.
try {
const result = await Promise.race([
messages.then(msg => ({ type: 'message', value: msg })),
signals.then(sig => ({ type: 'signal', value: sig })),
Promise.reject("no activity")
]);
if (result.type === 'message') {
console.log("received message", result.value);
} else {
console.log("received signal", result.value);
}
} catch (error) {
console.log("no activity");
}
}
main();
To run the program:
$ ts-node non-blocking-operations.ts
no message received
no message sent
no activity
This TypeScript code demonstrates how to implement non-blocking operations using Promises and async/await. While it doesn’t directly correspond to channels in other languages, it achieves similar functionality in an idiomatic TypeScript way.
The Promise.race
function is used to simulate the behavior of a select
statement with a default
case. It allows us to attempt an operation and immediately fall back to a default action if the operation doesn’t complete instantly.
Remember that this is a simplified example and real-world scenarios might require more robust error handling and resource management.