async/await & Error Handling

Promise-এর উপর সিনট্যাক্স sugar — sync-এর মতো দেখায়

~35 min Intermediate 16 practice problems Live runner

1. async Functions Always Return Promises

async.js
async function greet() {
    return "hello";        // auto-wrapped in Promise
}
greet().then(console.log);   // "hello"

// Throw inside async = rejected promise
async function boom() {
    throw new Error("oops");
}
boom().catch(e => console.log("caught:", e.message));
যেকোনো async function Promise return করে। ভেতরে কোনো error throw করলে সেটি rejected promise হয়।

2. await — Pause Until Settled

await.js
const wait = (ms, v) => new Promise(r => setTimeout(() => r(v), ms));

async function flow() {
    const a = await wait(10, 1);
    const b = await wait(10, 2);
    const c = await wait(10, 3);
    return a + b + c;
}

flow().then(console.log);   // 6

3. try / catch Around await

trycatch.js
async function load() {
    try {
        const data = await Promise.reject(new Error("network"));
        return data;
    } catch (err) {
        console.log("handled:", err.message);
        return null;
    } finally {
        console.log("cleanup");
    }
}

load().then(v => console.log("value:", v));

4. The Sequential-Loop Trap

Awaiting inside a loop runs items one after another. If they're independent, run them in parallel with Promise.all.

parallel.js
const wait = (ms, v) => new Promise(r => setTimeout(() => r(v), ms));

(async () => {
    const ids = [1, 2, 3];

    // Sequential — ~150 ms total
    const t1 = Date.now();
    for (const id of ids) await wait(50, id);
    console.log("sequential:", Date.now() - t1);

    // Parallel — ~50 ms total
    const t2 = Date.now();
    await Promise.all(ids.map(id => wait(50, id)));
    console.log("parallel  :", Date.now() - t2);
})();
Common bug for (const x of arr) await fetch(x) is sequential. If the requests are independent, this is 10× too slow. Use await Promise.all(arr.map(fetch)).

5. Top-Level Await

Inside an ES module you can use await at the top level — no wrapper IIFE needed.

// app.mjs
const data = await fetch("/api/feed").then(r => r.json());
export default data;

6. Mixing Sync & Async Errors

mix.js
async function parseAndFetch(s) {
    try {
        const obj = JSON.parse(s);    // sync throw
        const data = await fakeNet(obj.id); // async reject
        return data;
    } catch (e) {
        console.log("caught:", e.message);
    }
}

async function fakeNet(id) {
    if (!id) throw new Error("id missing");
    return `fetched #${id}`;
}

parseAndFetch("not-json");
parseAndFetch('{"id":0}');
parseAndFetch('{"id":42}').then(console.log);

7. Glossary (শব্দকোষ)

TermMeaningবাংলায়
asyncMarks a function so it always returns a Promise.Function-কে চিহ্নিত করে — সবসময় Promise ফেরত দেয়।
awaitPauses the async function until the awaited Promise settles.Promise settle না হওয়া পর্যন্ত function pause।
try/catchSync error trap — also catches errors thrown by await.Sync error catch করে; await-এর error-ও।
SequentialAwaiting one task at a time inside a loop — slower.Loop-এ এক-এক করে await করা — slow।
ParallelRunning independent tasks together with Promise.all.Independent task একসাথে চালানো।
Top-level awaitawait at the top of an ES module.ES module-এর top-level-এ await।
Fire-and-forgetCalling an async function without await — risky.await ছাড়া async call — error চাপা পড়ে।
For-await-ofIterates over an async iterable, awaiting each value.Async iterable-এর প্রতিটি value await করে।
সারাংশ: async/await Promise-এর উপর syntax sugar — কোড sync-এর মতো দেখায়, কিন্তু underneath এখনো Promise। Independent task-এ await Promise.all([...]) ব্যবহার করুন; loop-এ একে একে await করলে অপ্রয়োজনে slow। ES module-এ top-level await সরাসরি কাজ করে।

8. Practice Problems

  1. Write an async function that returns 42.
    ✨ Show Answer
    a1.js
    async function f() { return 42; }
    f().then(console.log);
  2. Use await on a 50ms timer.
    ✨ Show Answer
    a2.js
    (async () => {
        await new Promise(r => setTimeout(r, 50));
        console.log("done");
    })();
  3. Catch a rejected promise with try/catch.
    ✨ Show Answer
    a3.js
    (async () => {
        try { await Promise.reject("x"); }
        catch (e) { console.log("caught:", e); }
    })();
  4. Run three independent waits in parallel.
    ✨ Show Answer
    a4.js
    const w = (v, ms) => new Promise(r => setTimeout(() => r(v), ms));
    (async () => {
        const [a, b, c] = await Promise.all([w(1, 10), w(2, 10), w(3, 10)]);
        console.log(a, b, c);
    })();
  5. Show that throwing inside an async function makes the returned promise reject.
    ✨ Show Answer
    a5.js
    async function bad() { throw new Error("x"); }
    bad().catch(e => console.log("rejected:", e.message));
  6. Compare sequential and parallel timing for 5 50-ms tasks.
    ✨ Show Answer
    a6.js
    const w = (ms) => new Promise(r => setTimeout(r, ms));
    (async () => {
        const ms = [50,50,50,50,50];
        let t = Date.now();
        for (const n of ms) await w(n);
        console.log("seq:", Date.now() - t);
        t = Date.now();
        await Promise.all(ms.map(w));
        console.log("par:", Date.now() - t);
    })();
  7. Promisify setTimeout as sleep and use with await.
    ✨ Show Answer
    a7.js
    const sleep = ms => new Promise(r => setTimeout(r, ms));
    (async () => {
        console.log("start");
        await sleep(30);
        console.log("after 30ms");
    })();
  8. Build retry(fn, n) using async/await.
    ✨ Show Answer
    a8.js
    async function retry(fn, n) {
        for (let i = 0; i < n; i++) {
            try { return await fn(); }
            catch (e) { if (i === n - 1) throw e; }
        }
    }
    let i = 0;
    retry(() => ++i < 3 ? Promise.reject("x") : Promise.resolve("ok"), 5)
        .then(console.log);
  9. Show the wrong way: forgetting to await an async function.
    ✨ Show Answer
    a9.js
    async function val() { return 42; }
    async function main() {
        const v = val();        // missing await — v is a Promise
        console.log("got:", v);
        console.log("awaited:", await v);
    }
    main();
  10. Use try/catch/finally to log "cleanup" on both success and failure.
    ✨ Show Answer
    a10.js
    (async () => {
        try { await Promise.reject("err"); }
        catch (e) { console.log("caught", e); }
        finally { console.log("cleanup"); }
    })();
  11. Why is awaiting in a for-of loop sometimes correct (despite being slower)?
    ✨ Show Answer

    Answer: Sometimes order matters or each step depends on the previous result (e.g. paginated APIs, transactional writes). In those cases sequential is the right choice. Use Promise.all only when items are independent.

  12. Show top-level await syntactically (with explanation, since runner can't simulate modules).
    ✨ Show Answer

    Inside an ES module file (.mjs or with "type": "module"), this works at the top level:

    // app.mjs
    const config = await fetch("/config.json").then(r => r.json());
    export default config;
  13. Write a function that fetches three URLs in parallel and returns when ALL settle.
    ✨ Show Answer
    a13.js
    const fake = (v, ms, fail) => new Promise((res, rej) =>
        setTimeout(() => fail ? rej(v) : res(v), ms));
    (async () => {
        const r = await Promise.allSettled([
            fake("a", 10),
            fake("b", 10, true),
            fake("c", 10)
        ]);
        console.log(r);
    })();
  14. Implement a simple async queue with concurrency 1.
    ✨ Show Answer
    a14.js
    function serial() {
        let last = Promise.resolve();
        return task => (last = last.then(task, task));
    }
    const run = serial();
    run(() => new Promise(r => setTimeout(() => { console.log("a"); r(); }, 30)));
    run(() => new Promise(r => setTimeout(() => { console.log("b"); r(); }, 30)));
  15. Convert a Promise chain (.then.then.catch) to async/await.
    ✨ Show Answer
    a15.js
    const step = v => Promise.resolve(v + 1);
    
    (async () => {
        try {
            const a = await step(1);
            const b = await step(a);
            const c = await step(b);
            console.log(c);
        } catch (e) { console.log("err", e); }
    })();
  16. In one paragraph, explain why async/await beats raw Promises.
    ✨ Show Answer

    Answer: async/await reuses try/catch for error handling, eliminates the "forgot to return" trap inside .then, lets you mix sync and async errors in one place, and keeps control flow visually linear so you can use ordinary if/for with awaits inline. Underneath, it is still Promises — so all the combinators still work — but the surface code is dramatically easier to read and refactor.

Summary — Module 23

async functions return Promises. await pauses inside them until the awaited Promise settles. try/catch/finally handles errors uniformly. Run independent work in parallel with Promise.all rather than sequentially in a loop. ES modules support top-level await.

async/await Promise-এর উপর সিনট্যাক্স sugar — কোড sync-এর মতো দেখায়। Independent task-এ Promise.all; sequence-এ for-of।

Next Module → Fetch API ও JSON।