Timeouts in TypeScript

Here’s the TypeScript translation of the Go code example for timeouts:

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in TypeScript is straightforward using Promises and setTimeout.

import { setTimeout } from 'timers/promises';

async function main() {
    // For our example, suppose we're executing an external
    // call that returns its result as a Promise that resolves
    // after 2s. This is a common pattern in asynchronous programming.
    const externalCall = async (): Promise<string> => {
        await new Promise(resolve => setTimeout(resolve, 2000));
        return "result 1";
    };

    // Here's the Promise.race implementing a timeout.
    // We create a Promise that rejects after 1 second,
    // and race it against our external call.
    try {
        const result = await Promise.race([
            externalCall(),
            setTimeout(1000).then(() => { throw new Error("timeout 1"); })
        ]);
        console.log(result);
    } catch (error) {
        console.log((error as Error).message);
    }

    // If we allow a longer timeout of 3s, then the external
    // call will succeed and we'll print the result.
    try {
        const result = await Promise.race([
            externalCall(),
            setTimeout(3000).then(() => { throw new Error("timeout 2"); })
        ]);
        console.log(result);
    } catch (error) {
        console.log((error as Error).message);
    }
}

main();

Running this program shows the first operation timing out and the second succeeding.

$ ts-node timeouts.ts
timeout 1
result 1

In this TypeScript version:

  1. We use async/await syntax for handling asynchronous operations, which is more idiomatic in TypeScript than using callbacks.

  2. Instead of channels, we use Promises. The externalCall function returns a Promise that resolves after 2 seconds.

  3. We implement the timeout using Promise.race. This function takes an array of Promises and resolves or rejects as soon as one of the Promises in the array resolves or rejects.

  4. We use setTimeout from the timers/promises module, which returns a Promise that resolves after the specified delay.

  5. Error handling is done using try/catch blocks, which is the standard way to handle errors in asynchronous TypeScript code.

This approach provides similar functionality to the original example, allowing us to set timeouts for asynchronous operations in a clear and readable manner.