Skip to main content

async-await-and-error-handling

  • For TypeScript, please give 15 key points, tips and tricks I should know for a job interview for what we should know about Async/Await and Error Handling

Async/Await and Error Handling:

  • Async/await:

    The async/await pattern in TypeScript allows you to write code that handles asynchronous operations in a sequence that looks like standard synchronous code.

    async function fetchData() {
    const data = await someAsyncDataFunction();
    console.log(data);
    }
  • Async functions:

    Functions defined with the async keyword return a promise, and the resolved value is what the function returns.

    async function getNumber(): Promise<number> {
    return 42;
    }
  • Await keyword:

    The await keyword pauses the function's execution until the promise is settled, then resumes with the promise's result.

    async function showData() {
    const data = await fetchData(); // Waits here until fetchData resolves
    console.log(data);
    }
  • Code readability:

    Using async/await helps in writing cleaner code as it avoids nesting then-callbacks.

    // Instead of chaining with .then()
    fetchData().then(data => {
    console.log(data);
    });

    // You can write
    async function displayData() {
    const data = await fetchData();
    console.log(data);
    }
  • Error handling:

    Async functions can use try/catch blocks for error handling, which can make error handling logic clearer.

    async function safeFetch() {
    try {
    const data = await fetchData();
    console.log(data);
    } catch (error) {
    console.error("An error occurred:", error);
    }
    }
  • Type checking:

    TypeScript checks the types within async functions, ensuring that the returned promise resolves to the expected type.

    async function fetchTypedData(): Promise<string> {
    return await someStringReturningAsyncFunction();
    }
  • Error propagation:

    In async functions, errors from rejected promises are thrown, similar to throwing exceptions in synchronous code.

    async function riskyFetch() {
    const data = await fetchWithPossibleRejection(); // This can throw
    return data;
    }
    ```- **Return types:**

    The return type of an async function is always a Promise. You can specify the type that the Promise will resolve to.

    ```typescript
    async function fetchJson(url: string): Promise<JsonType> {
    const response = await fetch(url);
    return response.json();
    }
  • Unhandled rejections:

    Always handle promise rejections to avoid runtime errors. This can be done within the async function or at the call site.

    async function fetchDataSafely() {
    try {
    const data = await fetchData();
    return data;
    } catch (error) {
    console.error("Caught an unhandled rejection:", error);
    }
    }
  • Control flows:

    Async/await makes it easier to write control flows for asynchronous operations, like waiting for multiple promises in sequence or parallel.

    async function sequentialStart() {
    const first = await firstAsyncOperation();
    const second = await secondAsyncOperation(first);
    return second;
    }

    async function parallelStart() {
    const [firstResult, secondResult] = await Promise.all([
    firstAsyncOperation(),
    secondAsyncOperation(),
    ]);
    return { firstResult, secondResult };
    }
  • Type inference:

    TypeScript infers the type within an async function from the awaited expressions, which helps in maintaining a strong type system.

    async function getNumber(): Promise<number> {
    const num = await Promise.resolve(42);
    return num; // TypeScript infers `num` as `number`
    }
  • Performance consideration:

    Use async/await wisely; in cases where operations could run concurrently, use Promise.all to run them in parallel.

    async function fetchDataInParallel(urls: string[]) {
    return Promise.all(urls.map(url => fetch(url).then(resp => resp.json())));
    }
  • Combining with promises:

    Async functions can be used alongside traditional promise chains if needed.

    async function fetchDataWithThen() {
    const data = await fetchData();
    data.then(processData).catch(handleError);
    }
  • Strict mode compatibility:

    Async/await is compatible with TypeScript's strict mode, which can help catch potential issues at compile time.

    // In strict mode, TypeScript will enforce more rigorous checks
  • Asynchronous iteration:

    Use the for-await-of loop to iterate over data that is received asynchronously, such as streams.

    async function processAsyncIterable(iterable: AsyncIterable<Type>) {
    for await (const item of iterable) {
    processItem(item);
    }
    }

Mastering async/await and proper error handling in TypeScript is key to writing high-quality asynchronous code that is both robust and easy to maintain.