[{"data":1,"prerenderedAt":3997},["ShallowReactive",2],{"page-\u002Fjs\u002F17-async-await":3},{"id":4,"title":5,"body":6,"description":3990,"extension":3991,"meta":3992,"navigation":62,"path":3993,"seo":3994,"stem":3995,"__hash__":3996},"content\u002Fjs\u002F17-async-await.md","JavaScript 17 — async\u002Fawait Internals: Generator Semantics, Error Handling & Concurrency",{"type":7,"value":8,"toc":3976},"minimark",[9,14,24,563,567,1157,1164,1732,1740,2237,2241,2472,2476,2980,2984,3449,3453,3768,3772,3776,3865,3972],[10,11,13],"h1",{"id":12},"_17-asyncawait-internals-generator-semantics-error-handling-concurrency","17 — async\u002Fawait Internals: Generator Semantics, Error Handling & Concurrency",[15,16,18,19,23],"h2",{"id":17},"how-asyncawait-desugars-to-promises","How ",[20,21,22],"code",{},"async\u002Fawait"," Desugars to Promises",[25,26,28],"code-wrapper",{"language":27},"javascript",[29,30,34],"pre",{"className":31,"code":32,"language":27,"meta":33,"style":33},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F ── `async function` always returns a Promise ──\n\u002F\u002F If you return a value, it's wrapped in Promise.resolve.\n\u002F\u002F If you throw, it's wrapped in Promise.reject.\n\nasync function foo() { return 42; }\nfoo();  \u002F\u002F Promise { \u003Cfulfilled>: 42 } (returns a Promise, not 42 directly)\n\nasync function bar() { throw new Error(\"boom\"); }\nbar();  \u002F\u002F Promise { \u003Crejected>: Error: boom } (throws → rejected Promise)\n\n\u002F\u002F ── `await` suspends the function until the Promise settles ──\n\u002F\u002F await is syntactic sugar over .then — it pauses the async function, yielding to the event loop.\n\n\u002F\u002F async\u002Fawait:\nasync function loadData() {\n    const response = await fetch(\"\u002Fapi\u002Fdata\");  \u002F\u002F suspends until fetch resolves\n    const data = await response.json();          \u002F\u002F suspends until json resolves\n    return data;\n}\n\n\u002F\u002F Desugared (roughly — simplified):\nfunction loadDataDesugared() {\n    return fetch(\"\u002Fapi\u002Fdata\")\n        .then(response => response.json())\n        .then(data => data);\n}\n\n\u002F\u002F ── await unwraps the Promise value (or throws if rejected) ──\nasync function example() {\n    try {\n        const value = await Promise.resolve(42);  \u002F\u002F unwraps → 42\n        console.log(value);  \u002F\u002F 42\n\n        const error = await Promise.reject(new Error(\"fail\"));  \u002F\u002F throws\n    } catch (e) {\n        console.log(\"caught:\", e.message);  \u002F\u002F \"caught: fail\"\n    }\n}\n\n\u002F\u002F ── await on a non-Promise value ──\nconst result = await 42;  \u002F\u002F wraps 42 in Promise.resolve(42) → unwraps to 42\nconst result2 = await null;  \u002F\u002F wraps null → null\n\u002F\u002F await on a non-Promise is essentially synchronous (but still yields to the event loop once).\n","",[20,35,36,45,51,57,64,92,104,109,140,151,156,162,168,173,179,192,221,245,254,260,265,271,282,296,321,338,343,348,354,366,375,407,422,427,464,476,494,500,505,510,516,537,557],{"__ignoreMap":33},[37,38,41],"span",{"class":39,"line":40},"line",1,[37,42,44],{"class":43},"sdCPZ","\u002F\u002F ── `async function` always returns a Promise ──\n",[37,46,48],{"class":39,"line":47},2,[37,49,50],{"class":43},"\u002F\u002F If you return a value, it's wrapped in Promise.resolve.\n",[37,52,54],{"class":39,"line":53},3,[37,55,56],{"class":43},"\u002F\u002F If you throw, it's wrapped in Promise.reject.\n",[37,58,60],{"class":39,"line":59},4,[37,61,63],{"emptyLinePlaceholder":62},true,"\n",[37,65,67,71,74,78,82,85,89],{"class":39,"line":66},5,[37,68,70],{"class":69},"svdQ7","async",[37,72,73],{"class":69}," function",[37,75,77],{"class":76},"sIsaT"," foo",[37,79,81],{"class":80},"ssxIu","() { ",[37,83,84],{"class":69},"return",[37,86,88],{"class":87},"snvgF"," 42",[37,90,91],{"class":80},"; }\n",[37,93,95,98,101],{"class":39,"line":94},6,[37,96,97],{"class":76},"foo",[37,99,100],{"class":80},"();  ",[37,102,103],{"class":43},"\u002F\u002F Promise { \u003Cfulfilled>: 42 } (returns a Promise, not 42 directly)\n",[37,105,107],{"class":39,"line":106},7,[37,108,63],{"emptyLinePlaceholder":62},[37,110,112,114,116,119,121,124,127,130,133,137],{"class":39,"line":111},8,[37,113,70],{"class":69},[37,115,73],{"class":69},[37,117,118],{"class":76}," bar",[37,120,81],{"class":80},[37,122,123],{"class":69},"throw",[37,125,126],{"class":69}," new",[37,128,129],{"class":76}," Error",[37,131,132],{"class":80},"(",[37,134,136],{"class":135},"sJ6F3","\"boom\"",[37,138,139],{"class":80},"); }\n",[37,141,143,146,148],{"class":39,"line":142},9,[37,144,145],{"class":76},"bar",[37,147,100],{"class":80},[37,149,150],{"class":43},"\u002F\u002F Promise { \u003Crejected>: Error: boom } (throws → rejected Promise)\n",[37,152,154],{"class":39,"line":153},10,[37,155,63],{"emptyLinePlaceholder":62},[37,157,159],{"class":39,"line":158},11,[37,160,161],{"class":43},"\u002F\u002F ── `await` suspends the function until the Promise settles ──\n",[37,163,165],{"class":39,"line":164},12,[37,166,167],{"class":43},"\u002F\u002F await is syntactic sugar over .then — it pauses the async function, yielding to the event loop.\n",[37,169,171],{"class":39,"line":170},13,[37,172,63],{"emptyLinePlaceholder":62},[37,174,176],{"class":39,"line":175},14,[37,177,178],{"class":43},"\u002F\u002F async\u002Fawait:\n",[37,180,182,184,186,189],{"class":39,"line":181},15,[37,183,70],{"class":69},[37,185,73],{"class":69},[37,187,188],{"class":76}," loadData",[37,190,191],{"class":80},"() {\n",[37,193,195,198,201,204,207,210,212,215,218],{"class":39,"line":194},16,[37,196,197],{"class":69},"    const",[37,199,200],{"class":87}," response",[37,202,203],{"class":69}," =",[37,205,206],{"class":69}," await",[37,208,209],{"class":76}," fetch",[37,211,132],{"class":80},[37,213,214],{"class":135},"\"\u002Fapi\u002Fdata\"",[37,216,217],{"class":80},");  ",[37,219,220],{"class":43},"\u002F\u002F suspends until fetch resolves\n",[37,222,224,226,229,231,233,236,239,242],{"class":39,"line":223},17,[37,225,197],{"class":69},[37,227,228],{"class":87}," data",[37,230,203],{"class":69},[37,232,206],{"class":69},[37,234,235],{"class":80}," response.",[37,237,238],{"class":76},"json",[37,240,241],{"class":80},"();          ",[37,243,244],{"class":43},"\u002F\u002F suspends until json resolves\n",[37,246,248,251],{"class":39,"line":247},18,[37,249,250],{"class":69},"    return",[37,252,253],{"class":80}," data;\n",[37,255,257],{"class":39,"line":256},19,[37,258,259],{"class":80},"}\n",[37,261,263],{"class":39,"line":262},20,[37,264,63],{"emptyLinePlaceholder":62},[37,266,268],{"class":39,"line":267},21,[37,269,270],{"class":43},"\u002F\u002F Desugared (roughly — simplified):\n",[37,272,274,277,280],{"class":39,"line":273},22,[37,275,276],{"class":69},"function",[37,278,279],{"class":76}," loadDataDesugared",[37,281,191],{"class":80},[37,283,285,287,289,291,293],{"class":39,"line":284},23,[37,286,250],{"class":69},[37,288,209],{"class":76},[37,290,132],{"class":80},[37,292,214],{"class":135},[37,294,295],{"class":80},")\n",[37,297,299,302,305,307,311,314,316,318],{"class":39,"line":298},24,[37,300,301],{"class":80},"        .",[37,303,304],{"class":76},"then",[37,306,132],{"class":80},[37,308,310],{"class":309},"sCrzJ","response",[37,312,313],{"class":69}," =>",[37,315,235],{"class":80},[37,317,238],{"class":76},[37,319,320],{"class":80},"())\n",[37,322,324,326,328,330,333,335],{"class":39,"line":323},25,[37,325,301],{"class":80},[37,327,304],{"class":76},[37,329,132],{"class":80},[37,331,332],{"class":309},"data",[37,334,313],{"class":69},[37,336,337],{"class":80}," data);\n",[37,339,341],{"class":39,"line":340},26,[37,342,259],{"class":80},[37,344,346],{"class":39,"line":345},27,[37,347,63],{"emptyLinePlaceholder":62},[37,349,351],{"class":39,"line":350},28,[37,352,353],{"class":43},"\u002F\u002F ── await unwraps the Promise value (or throws if rejected) ──\n",[37,355,357,359,361,364],{"class":39,"line":356},29,[37,358,70],{"class":69},[37,360,73],{"class":69},[37,362,363],{"class":76}," example",[37,365,191],{"class":80},[37,367,369,372],{"class":39,"line":368},30,[37,370,371],{"class":69},"    try",[37,373,374],{"class":80}," {\n",[37,376,378,381,384,386,388,391,394,397,399,402,404],{"class":39,"line":377},31,[37,379,380],{"class":69},"        const",[37,382,383],{"class":87}," value",[37,385,203],{"class":69},[37,387,206],{"class":69},[37,389,390],{"class":87}," Promise",[37,392,393],{"class":80},".",[37,395,396],{"class":76},"resolve",[37,398,132],{"class":80},[37,400,401],{"class":87},"42",[37,403,217],{"class":80},[37,405,406],{"class":43},"\u002F\u002F unwraps → 42\n",[37,408,410,413,416,419],{"class":39,"line":409},32,[37,411,412],{"class":80},"        console.",[37,414,415],{"class":76},"log",[37,417,418],{"class":80},"(value);  ",[37,420,421],{"class":43},"\u002F\u002F 42\n",[37,423,425],{"class":39,"line":424},33,[37,426,63],{"emptyLinePlaceholder":62},[37,428,430,432,435,437,439,441,443,446,448,451,453,455,458,461],{"class":39,"line":429},34,[37,431,380],{"class":69},[37,433,434],{"class":87}," error",[37,436,203],{"class":69},[37,438,206],{"class":69},[37,440,390],{"class":87},[37,442,393],{"class":80},[37,444,445],{"class":76},"reject",[37,447,132],{"class":80},[37,449,450],{"class":69},"new",[37,452,129],{"class":76},[37,454,132],{"class":80},[37,456,457],{"class":135},"\"fail\"",[37,459,460],{"class":80},"));  ",[37,462,463],{"class":43},"\u002F\u002F throws\n",[37,465,467,470,473],{"class":39,"line":466},35,[37,468,469],{"class":80},"    } ",[37,471,472],{"class":69},"catch",[37,474,475],{"class":80}," (e) {\n",[37,477,479,481,483,485,488,491],{"class":39,"line":478},36,[37,480,412],{"class":80},[37,482,415],{"class":76},[37,484,132],{"class":80},[37,486,487],{"class":135},"\"caught:\"",[37,489,490],{"class":80},", e.message);  ",[37,492,493],{"class":43},"\u002F\u002F \"caught: fail\"\n",[37,495,497],{"class":39,"line":496},37,[37,498,499],{"class":80},"    }\n",[37,501,503],{"class":39,"line":502},38,[37,504,259],{"class":80},[37,506,508],{"class":39,"line":507},39,[37,509,63],{"emptyLinePlaceholder":62},[37,511,513],{"class":39,"line":512},40,[37,514,515],{"class":43},"\u002F\u002F ── await on a non-Promise value ──\n",[37,517,519,522,525,527,529,531,534],{"class":39,"line":518},41,[37,520,521],{"class":69},"const",[37,523,524],{"class":87}," result",[37,526,203],{"class":69},[37,528,206],{"class":69},[37,530,88],{"class":87},[37,532,533],{"class":80},";  ",[37,535,536],{"class":43},"\u002F\u002F wraps 42 in Promise.resolve(42) → unwraps to 42\n",[37,538,540,542,545,547,549,552,554],{"class":39,"line":539},42,[37,541,521],{"class":69},[37,543,544],{"class":87}," result2",[37,546,203],{"class":69},[37,548,206],{"class":69},[37,550,551],{"class":87}," null",[37,553,533],{"class":80},[37,555,556],{"class":43},"\u002F\u002F wraps null → null\n",[37,558,560],{"class":39,"line":559},43,[37,561,562],{"class":43},"\u002F\u002F await on a non-Promise is essentially synchronous (but still yields to the event loop once).\n",[15,564,566],{"id":565},"sequential-vs-concurrent-execution","Sequential vs Concurrent Execution",[25,568,569],{"language":27},[29,570,572],{"className":31,"code":571,"language":27,"meta":33,"style":33},"\u002F\u002F ❌ SLOW — sequential await (each waits for the previous to finish)\nasync function sequential() {\n    const a = await fetch(\"\u002Fapi\u002Fa\");  \u002F\u002F waits for A (2s)\n    const b = await fetch(\"\u002Fapi\u002Fb\");  \u002F\u002F waits for B (2s) — starts AFTER A finishes\n    const c = await fetch(\"\u002Fapi\u002Fc\");  \u002F\u002F waits for C (2s) — starts AFTER B finishes\n    return [a, b, c];\n}\n\u002F\u002F Total: 2 + 2 + 2 = 6s (sequential — each request waits for the previous)\n\n\u002F\u002F ✅ FAST — concurrent with Promise.all (all start at once)\nasync function concurrent() {\n    const [a, b, c] = await Promise.all([\n        fetch(\"\u002Fapi\u002Fa\"),  \u002F\u002F starts immediately\n        fetch(\"\u002Fapi\u002Fb\"),  \u002F\u002F starts immediately (concurrent)\n        fetch(\"\u002Fapi\u002Fc\"),  \u002F\u002F starts immediately (concurrent)\n    ]);\n    return [a, b, c];\n}\n\u002F\u002F Total: max(2, 2, 2) = 2s (concurrent — all start at the same time)\n\n\u002F\u002F ── Mixed: some sequential, some concurrent ──\nasync function mixed() {\n    \u002F\u002F Sequential: need the user ID before we can fetch posts\n    const user = await fetch(\"\u002Fapi\u002Fuser\").then(r => r.json());\n    \u002F\u002F Concurrent: fetch posts and friends in parallel (both need user.id)\n    const [posts, friends] = await Promise.all([\n        fetch(`\u002Fapi\u002Fposts?userId=${user.id}`).then(r => r.json()),\n        fetch(`\u002Fapi\u002Ffriends?userId=${user.id}`).then(r => r.json()),\n    ]);\n    return { user, posts, friends };\n}\n\n\u002F\u002F ── Start a Promise without awaiting (fire and forget) ──\nasync function fireAndForget() {\n    const promise = fetch(\"\u002Fapi\u002Flog\");  \u002F\u002F start but don't await (don't block)\n    doOtherWork();  \u002F\u002F runs immediately (doesn't wait for fetch)\n    await promise;  \u002F\u002F await later (if you need the result)\n}\n\n\u002F\u002F ── `await` yields to the event loop (microtask boundary) ──\nasync function yields() {\n    console.log(\"A\");\n    await Promise.resolve();  \u002F\u002F yields — other code can run here\n    console.log(\"C\");  \u002F\u002F runs as a microtask (after current sync code)\n}\nconsole.log(\"B\");\nyields();\nconsole.log(\"D\");\n\u002F\u002F Output: B, A, D, C (await suspends, D runs, then C resumes as a microtask)\n",[20,573,574,579,590,613,636,659,666,670,675,679,684,695,734,749,762,774,779,785,789,794,798,803,814,819,857,862,890,927,960,964,971,975,979,984,995,1016,1026,1037,1041,1045,1050,1061,1076,1091,1108,1113,1128,1137,1151],{"__ignoreMap":33},[37,575,576],{"class":39,"line":40},[37,577,578],{"class":43},"\u002F\u002F ❌ SLOW — sequential await (each waits for the previous to finish)\n",[37,580,581,583,585,588],{"class":39,"line":47},[37,582,70],{"class":69},[37,584,73],{"class":69},[37,586,587],{"class":76}," sequential",[37,589,191],{"class":80},[37,591,592,594,597,599,601,603,605,608,610],{"class":39,"line":53},[37,593,197],{"class":69},[37,595,596],{"class":87}," a",[37,598,203],{"class":69},[37,600,206],{"class":69},[37,602,209],{"class":76},[37,604,132],{"class":80},[37,606,607],{"class":135},"\"\u002Fapi\u002Fa\"",[37,609,217],{"class":80},[37,611,612],{"class":43},"\u002F\u002F waits for A (2s)\n",[37,614,615,617,620,622,624,626,628,631,633],{"class":39,"line":59},[37,616,197],{"class":69},[37,618,619],{"class":87}," b",[37,621,203],{"class":69},[37,623,206],{"class":69},[37,625,209],{"class":76},[37,627,132],{"class":80},[37,629,630],{"class":135},"\"\u002Fapi\u002Fb\"",[37,632,217],{"class":80},[37,634,635],{"class":43},"\u002F\u002F waits for B (2s) — starts AFTER A finishes\n",[37,637,638,640,643,645,647,649,651,654,656],{"class":39,"line":66},[37,639,197],{"class":69},[37,641,642],{"class":87}," c",[37,644,203],{"class":69},[37,646,206],{"class":69},[37,648,209],{"class":76},[37,650,132],{"class":80},[37,652,653],{"class":135},"\"\u002Fapi\u002Fc\"",[37,655,217],{"class":80},[37,657,658],{"class":43},"\u002F\u002F waits for C (2s) — starts AFTER B finishes\n",[37,660,661,663],{"class":39,"line":94},[37,662,250],{"class":69},[37,664,665],{"class":80}," [a, b, c];\n",[37,667,668],{"class":39,"line":106},[37,669,259],{"class":80},[37,671,672],{"class":39,"line":111},[37,673,674],{"class":43},"\u002F\u002F Total: 2 + 2 + 2 = 6s (sequential — each request waits for the previous)\n",[37,676,677],{"class":39,"line":142},[37,678,63],{"emptyLinePlaceholder":62},[37,680,681],{"class":39,"line":153},[37,682,683],{"class":43},"\u002F\u002F ✅ FAST — concurrent with Promise.all (all start at once)\n",[37,685,686,688,690,693],{"class":39,"line":158},[37,687,70],{"class":69},[37,689,73],{"class":69},[37,691,692],{"class":76}," concurrent",[37,694,191],{"class":80},[37,696,697,699,702,705,708,711,713,716,719,722,724,726,728,731],{"class":39,"line":164},[37,698,197],{"class":69},[37,700,701],{"class":80}," [",[37,703,704],{"class":87},"a",[37,706,707],{"class":80},", ",[37,709,710],{"class":87},"b",[37,712,707],{"class":80},[37,714,715],{"class":87},"c",[37,717,718],{"class":80},"] ",[37,720,721],{"class":69},"=",[37,723,206],{"class":69},[37,725,390],{"class":87},[37,727,393],{"class":80},[37,729,730],{"class":76},"all",[37,732,733],{"class":80},"([\n",[37,735,736,739,741,743,746],{"class":39,"line":170},[37,737,738],{"class":76},"        fetch",[37,740,132],{"class":80},[37,742,607],{"class":135},[37,744,745],{"class":80},"),  ",[37,747,748],{"class":43},"\u002F\u002F starts immediately\n",[37,750,751,753,755,757,759],{"class":39,"line":175},[37,752,738],{"class":76},[37,754,132],{"class":80},[37,756,630],{"class":135},[37,758,745],{"class":80},[37,760,761],{"class":43},"\u002F\u002F starts immediately (concurrent)\n",[37,763,764,766,768,770,772],{"class":39,"line":181},[37,765,738],{"class":76},[37,767,132],{"class":80},[37,769,653],{"class":135},[37,771,745],{"class":80},[37,773,761],{"class":43},[37,775,776],{"class":39,"line":194},[37,777,778],{"class":80},"    ]);\n",[37,780,781,783],{"class":39,"line":223},[37,782,250],{"class":69},[37,784,665],{"class":80},[37,786,787],{"class":39,"line":247},[37,788,259],{"class":80},[37,790,791],{"class":39,"line":256},[37,792,793],{"class":43},"\u002F\u002F Total: max(2, 2, 2) = 2s (concurrent — all start at the same time)\n",[37,795,796],{"class":39,"line":262},[37,797,63],{"emptyLinePlaceholder":62},[37,799,800],{"class":39,"line":267},[37,801,802],{"class":43},"\u002F\u002F ── Mixed: some sequential, some concurrent ──\n",[37,804,805,807,809,812],{"class":39,"line":273},[37,806,70],{"class":69},[37,808,73],{"class":69},[37,810,811],{"class":76}," mixed",[37,813,191],{"class":80},[37,815,816],{"class":39,"line":284},[37,817,818],{"class":43},"    \u002F\u002F Sequential: need the user ID before we can fetch posts\n",[37,820,821,823,826,828,830,832,834,837,840,842,844,847,849,852,854],{"class":39,"line":298},[37,822,197],{"class":69},[37,824,825],{"class":87}," user",[37,827,203],{"class":69},[37,829,206],{"class":69},[37,831,209],{"class":76},[37,833,132],{"class":80},[37,835,836],{"class":135},"\"\u002Fapi\u002Fuser\"",[37,838,839],{"class":80},").",[37,841,304],{"class":76},[37,843,132],{"class":80},[37,845,846],{"class":309},"r",[37,848,313],{"class":69},[37,850,851],{"class":80}," r.",[37,853,238],{"class":76},[37,855,856],{"class":80},"());\n",[37,858,859],{"class":39,"line":323},[37,860,861],{"class":43},"    \u002F\u002F Concurrent: fetch posts and friends in parallel (both need user.id)\n",[37,863,864,866,868,871,873,876,878,880,882,884,886,888],{"class":39,"line":340},[37,865,197],{"class":69},[37,867,701],{"class":80},[37,869,870],{"class":87},"posts",[37,872,707],{"class":80},[37,874,875],{"class":87},"friends",[37,877,718],{"class":80},[37,879,721],{"class":69},[37,881,206],{"class":69},[37,883,390],{"class":87},[37,885,393],{"class":80},[37,887,730],{"class":76},[37,889,733],{"class":80},[37,891,892,894,896,899,902,904,907,910,912,914,916,918,920,922,924],{"class":39,"line":345},[37,893,738],{"class":76},[37,895,132],{"class":80},[37,897,898],{"class":135},"`\u002Fapi\u002Fposts?userId=${",[37,900,901],{"class":80},"user",[37,903,393],{"class":135},[37,905,906],{"class":80},"id",[37,908,909],{"class":135},"}`",[37,911,839],{"class":80},[37,913,304],{"class":76},[37,915,132],{"class":80},[37,917,846],{"class":309},[37,919,313],{"class":69},[37,921,851],{"class":80},[37,923,238],{"class":76},[37,925,926],{"class":80},"()),\n",[37,928,929,931,933,936,938,940,942,944,946,948,950,952,954,956,958],{"class":39,"line":350},[37,930,738],{"class":76},[37,932,132],{"class":80},[37,934,935],{"class":135},"`\u002Fapi\u002Ffriends?userId=${",[37,937,901],{"class":80},[37,939,393],{"class":135},[37,941,906],{"class":80},[37,943,909],{"class":135},[37,945,839],{"class":80},[37,947,304],{"class":76},[37,949,132],{"class":80},[37,951,846],{"class":309},[37,953,313],{"class":69},[37,955,851],{"class":80},[37,957,238],{"class":76},[37,959,926],{"class":80},[37,961,962],{"class":39,"line":356},[37,963,778],{"class":80},[37,965,966,968],{"class":39,"line":368},[37,967,250],{"class":69},[37,969,970],{"class":80}," { user, posts, friends };\n",[37,972,973],{"class":39,"line":377},[37,974,259],{"class":80},[37,976,977],{"class":39,"line":409},[37,978,63],{"emptyLinePlaceholder":62},[37,980,981],{"class":39,"line":424},[37,982,983],{"class":43},"\u002F\u002F ── Start a Promise without awaiting (fire and forget) ──\n",[37,985,986,988,990,993],{"class":39,"line":429},[37,987,70],{"class":69},[37,989,73],{"class":69},[37,991,992],{"class":76}," fireAndForget",[37,994,191],{"class":80},[37,996,997,999,1002,1004,1006,1008,1011,1013],{"class":39,"line":466},[37,998,197],{"class":69},[37,1000,1001],{"class":87}," promise",[37,1003,203],{"class":69},[37,1005,209],{"class":76},[37,1007,132],{"class":80},[37,1009,1010],{"class":135},"\"\u002Fapi\u002Flog\"",[37,1012,217],{"class":80},[37,1014,1015],{"class":43},"\u002F\u002F start but don't await (don't block)\n",[37,1017,1018,1021,1023],{"class":39,"line":478},[37,1019,1020],{"class":76},"    doOtherWork",[37,1022,100],{"class":80},[37,1024,1025],{"class":43},"\u002F\u002F runs immediately (doesn't wait for fetch)\n",[37,1027,1028,1031,1034],{"class":39,"line":496},[37,1029,1030],{"class":69},"    await",[37,1032,1033],{"class":80}," promise;  ",[37,1035,1036],{"class":43},"\u002F\u002F await later (if you need the result)\n",[37,1038,1039],{"class":39,"line":502},[37,1040,259],{"class":80},[37,1042,1043],{"class":39,"line":507},[37,1044,63],{"emptyLinePlaceholder":62},[37,1046,1047],{"class":39,"line":512},[37,1048,1049],{"class":43},"\u002F\u002F ── `await` yields to the event loop (microtask boundary) ──\n",[37,1051,1052,1054,1056,1059],{"class":39,"line":518},[37,1053,70],{"class":69},[37,1055,73],{"class":69},[37,1057,1058],{"class":76}," yields",[37,1060,191],{"class":80},[37,1062,1063,1066,1068,1070,1073],{"class":39,"line":539},[37,1064,1065],{"class":80},"    console.",[37,1067,415],{"class":76},[37,1069,132],{"class":80},[37,1071,1072],{"class":135},"\"A\"",[37,1074,1075],{"class":80},");\n",[37,1077,1078,1080,1082,1084,1086,1088],{"class":39,"line":559},[37,1079,1030],{"class":69},[37,1081,390],{"class":87},[37,1083,393],{"class":80},[37,1085,396],{"class":76},[37,1087,100],{"class":80},[37,1089,1090],{"class":43},"\u002F\u002F yields — other code can run here\n",[37,1092,1094,1096,1098,1100,1103,1105],{"class":39,"line":1093},44,[37,1095,1065],{"class":80},[37,1097,415],{"class":76},[37,1099,132],{"class":80},[37,1101,1102],{"class":135},"\"C\"",[37,1104,217],{"class":80},[37,1106,1107],{"class":43},"\u002F\u002F runs as a microtask (after current sync code)\n",[37,1109,1111],{"class":39,"line":1110},45,[37,1112,259],{"class":80},[37,1114,1116,1119,1121,1123,1126],{"class":39,"line":1115},46,[37,1117,1118],{"class":80},"console.",[37,1120,415],{"class":76},[37,1122,132],{"class":80},[37,1124,1125],{"class":135},"\"B\"",[37,1127,1075],{"class":80},[37,1129,1131,1134],{"class":39,"line":1130},47,[37,1132,1133],{"class":76},"yields",[37,1135,1136],{"class":80},"();\n",[37,1138,1140,1142,1144,1146,1149],{"class":39,"line":1139},48,[37,1141,1118],{"class":80},[37,1143,415],{"class":76},[37,1145,132],{"class":80},[37,1147,1148],{"class":135},"\"D\"",[37,1150,1075],{"class":80},[37,1152,1154],{"class":39,"line":1153},49,[37,1155,1156],{"class":43},"\u002F\u002F Output: B, A, D, C (await suspends, D runs, then C resumes as a microtask)\n",[15,1158,1160,1161],{"id":1159},"error-handling-with-trycatch","Error Handling with ",[20,1162,1163],{},"try\u002Fcatch",[25,1165,1166],{"language":27},[29,1167,1169],{"className":31,"code":1168,"language":27,"meta":33,"style":33},"\u002F\u002F ── try\u002Fcatch works with await (unlike Promises where you need .catch) ──\nasync function fetchData() {\n    try {\n        const response = await fetch(\"\u002Fapi\u002Fdata\");\n        if (!response.ok) throw new Error(`HTTP ${response.status}`);\n        return await response.json();\n    } catch (error) {\n        if (error instanceof TypeError) {\n            \u002F\u002F Network error (fetch failed entirely)\n            console.error(\"network error:\", error.message);\n        } else {\n            \u002F\u002F HTTP error (4xx, 5xx) or JSON parse error\n            console.error(\"fetch error:\", error.message);\n        }\n        throw error;  \u002F\u002F re-throw for the caller to handle (or return a default)\n    }\n}\n\n\u002F\u002F ── Multiple awaits in one try (all share one catch) ──\nasync function pipeline() {\n    try {\n        const user = await getUser();      \u002F\u002F any of these can throw\n        const posts = await getPosts(user); \u002F\u002F and all are caught here\n        const comments = await getComments(posts[0]);\n        return { user, posts, comments };\n    } catch (error) {\n        console.error(\"pipeline failed:\", error);\n        throw error;\n    }\n}\n\n\u002F\u002F ── Catch per await (different handling for each) ──\nasync function resilient() {\n    let user;\n    try {\n        user = await getUser();\n    } catch {\n        user = { name: \"anonymous\" };  \u002F\u002F fallback for user\n    }\n\n    let posts;\n    try {\n        posts = await getPosts(user);\n    } catch {\n        posts = [];  \u002F\u002F fallback for posts\n    }\n\n    return { user, posts };\n}\n\n\u002F\u002F ── finally with async\u002Fawait ──\nasync function withCleanup() {\n    const resource = await acquireResource();\n    try {\n        return await useResource(resource);\n    } finally {\n        await releaseResource(resource);  \u002F\u002F runs on both success and error\n    }\n}\n",[20,1170,1171,1176,1187,1193,1211,1247,1260,1269,1285,1290,1306,1316,1321,1334,1339,1350,1354,1358,1362,1367,1378,1384,1403,1423,1446,1453,1461,1475,1482,1486,1490,1494,1499,1510,1518,1524,1537,1545,1563,1567,1571,1578,1584,1598,1606,1618,1622,1626,1633,1637,1642,1648,1660,1677,1684,1697,1707,1722,1727],{"__ignoreMap":33},[37,1172,1173],{"class":39,"line":40},[37,1174,1175],{"class":43},"\u002F\u002F ── try\u002Fcatch works with await (unlike Promises where you need .catch) ──\n",[37,1177,1178,1180,1182,1185],{"class":39,"line":47},[37,1179,70],{"class":69},[37,1181,73],{"class":69},[37,1183,1184],{"class":76}," fetchData",[37,1186,191],{"class":80},[37,1188,1189,1191],{"class":39,"line":53},[37,1190,371],{"class":69},[37,1192,374],{"class":80},[37,1194,1195,1197,1199,1201,1203,1205,1207,1209],{"class":39,"line":59},[37,1196,380],{"class":69},[37,1198,200],{"class":87},[37,1200,203],{"class":69},[37,1202,206],{"class":69},[37,1204,209],{"class":76},[37,1206,132],{"class":80},[37,1208,214],{"class":135},[37,1210,1075],{"class":80},[37,1212,1213,1216,1219,1222,1225,1227,1229,1231,1233,1236,1238,1240,1243,1245],{"class":39,"line":66},[37,1214,1215],{"class":69},"        if",[37,1217,1218],{"class":80}," (",[37,1220,1221],{"class":69},"!",[37,1223,1224],{"class":80},"response.ok) ",[37,1226,123],{"class":69},[37,1228,126],{"class":69},[37,1230,129],{"class":76},[37,1232,132],{"class":80},[37,1234,1235],{"class":135},"`HTTP ${",[37,1237,310],{"class":80},[37,1239,393],{"class":135},[37,1241,1242],{"class":80},"status",[37,1244,909],{"class":135},[37,1246,1075],{"class":80},[37,1248,1249,1252,1254,1256,1258],{"class":39,"line":94},[37,1250,1251],{"class":69},"        return",[37,1253,206],{"class":69},[37,1255,235],{"class":80},[37,1257,238],{"class":76},[37,1259,1136],{"class":80},[37,1261,1262,1264,1266],{"class":39,"line":106},[37,1263,469],{"class":80},[37,1265,472],{"class":69},[37,1267,1268],{"class":80}," (error) {\n",[37,1270,1271,1273,1276,1279,1282],{"class":39,"line":111},[37,1272,1215],{"class":69},[37,1274,1275],{"class":80}," (error ",[37,1277,1278],{"class":69},"instanceof",[37,1280,1281],{"class":76}," TypeError",[37,1283,1284],{"class":80},") {\n",[37,1286,1287],{"class":39,"line":142},[37,1288,1289],{"class":43},"            \u002F\u002F Network error (fetch failed entirely)\n",[37,1291,1292,1295,1298,1300,1303],{"class":39,"line":153},[37,1293,1294],{"class":80},"            console.",[37,1296,1297],{"class":76},"error",[37,1299,132],{"class":80},[37,1301,1302],{"class":135},"\"network error:\"",[37,1304,1305],{"class":80},", error.message);\n",[37,1307,1308,1311,1314],{"class":39,"line":158},[37,1309,1310],{"class":80},"        } ",[37,1312,1313],{"class":69},"else",[37,1315,374],{"class":80},[37,1317,1318],{"class":39,"line":164},[37,1319,1320],{"class":43},"            \u002F\u002F HTTP error (4xx, 5xx) or JSON parse error\n",[37,1322,1323,1325,1327,1329,1332],{"class":39,"line":170},[37,1324,1294],{"class":80},[37,1326,1297],{"class":76},[37,1328,132],{"class":80},[37,1330,1331],{"class":135},"\"fetch error:\"",[37,1333,1305],{"class":80},[37,1335,1336],{"class":39,"line":175},[37,1337,1338],{"class":80},"        }\n",[37,1340,1341,1344,1347],{"class":39,"line":181},[37,1342,1343],{"class":69},"        throw",[37,1345,1346],{"class":80}," error;  ",[37,1348,1349],{"class":43},"\u002F\u002F re-throw for the caller to handle (or return a default)\n",[37,1351,1352],{"class":39,"line":194},[37,1353,499],{"class":80},[37,1355,1356],{"class":39,"line":223},[37,1357,259],{"class":80},[37,1359,1360],{"class":39,"line":247},[37,1361,63],{"emptyLinePlaceholder":62},[37,1363,1364],{"class":39,"line":256},[37,1365,1366],{"class":43},"\u002F\u002F ── Multiple awaits in one try (all share one catch) ──\n",[37,1368,1369,1371,1373,1376],{"class":39,"line":262},[37,1370,70],{"class":69},[37,1372,73],{"class":69},[37,1374,1375],{"class":76}," pipeline",[37,1377,191],{"class":80},[37,1379,1380,1382],{"class":39,"line":267},[37,1381,371],{"class":69},[37,1383,374],{"class":80},[37,1385,1386,1388,1390,1392,1394,1397,1400],{"class":39,"line":273},[37,1387,380],{"class":69},[37,1389,825],{"class":87},[37,1391,203],{"class":69},[37,1393,206],{"class":69},[37,1395,1396],{"class":76}," getUser",[37,1398,1399],{"class":80},"();      ",[37,1401,1402],{"class":43},"\u002F\u002F any of these can throw\n",[37,1404,1405,1407,1410,1412,1414,1417,1420],{"class":39,"line":284},[37,1406,380],{"class":69},[37,1408,1409],{"class":87}," posts",[37,1411,203],{"class":69},[37,1413,206],{"class":69},[37,1415,1416],{"class":76}," getPosts",[37,1418,1419],{"class":80},"(user); ",[37,1421,1422],{"class":43},"\u002F\u002F and all are caught here\n",[37,1424,1425,1427,1430,1432,1434,1437,1440,1443],{"class":39,"line":298},[37,1426,380],{"class":69},[37,1428,1429],{"class":87}," comments",[37,1431,203],{"class":69},[37,1433,206],{"class":69},[37,1435,1436],{"class":76}," getComments",[37,1438,1439],{"class":80},"(posts[",[37,1441,1442],{"class":87},"0",[37,1444,1445],{"class":80},"]);\n",[37,1447,1448,1450],{"class":39,"line":323},[37,1449,1251],{"class":69},[37,1451,1452],{"class":80}," { user, posts, comments };\n",[37,1454,1455,1457,1459],{"class":39,"line":340},[37,1456,469],{"class":80},[37,1458,472],{"class":69},[37,1460,1268],{"class":80},[37,1462,1463,1465,1467,1469,1472],{"class":39,"line":345},[37,1464,412],{"class":80},[37,1466,1297],{"class":76},[37,1468,132],{"class":80},[37,1470,1471],{"class":135},"\"pipeline failed:\"",[37,1473,1474],{"class":80},", error);\n",[37,1476,1477,1479],{"class":39,"line":350},[37,1478,1343],{"class":69},[37,1480,1481],{"class":80}," error;\n",[37,1483,1484],{"class":39,"line":356},[37,1485,499],{"class":80},[37,1487,1488],{"class":39,"line":368},[37,1489,259],{"class":80},[37,1491,1492],{"class":39,"line":377},[37,1493,63],{"emptyLinePlaceholder":62},[37,1495,1496],{"class":39,"line":409},[37,1497,1498],{"class":43},"\u002F\u002F ── Catch per await (different handling for each) ──\n",[37,1500,1501,1503,1505,1508],{"class":39,"line":424},[37,1502,70],{"class":69},[37,1504,73],{"class":69},[37,1506,1507],{"class":76}," resilient",[37,1509,191],{"class":80},[37,1511,1512,1515],{"class":39,"line":429},[37,1513,1514],{"class":69},"    let",[37,1516,1517],{"class":80}," user;\n",[37,1519,1520,1522],{"class":39,"line":466},[37,1521,371],{"class":69},[37,1523,374],{"class":80},[37,1525,1526,1529,1531,1533,1535],{"class":39,"line":478},[37,1527,1528],{"class":80},"        user ",[37,1530,721],{"class":69},[37,1532,206],{"class":69},[37,1534,1396],{"class":76},[37,1536,1136],{"class":80},[37,1538,1539,1541,1543],{"class":39,"line":496},[37,1540,469],{"class":80},[37,1542,472],{"class":69},[37,1544,374],{"class":80},[37,1546,1547,1549,1551,1554,1557,1560],{"class":39,"line":502},[37,1548,1528],{"class":80},[37,1550,721],{"class":69},[37,1552,1553],{"class":80}," { name: ",[37,1555,1556],{"class":135},"\"anonymous\"",[37,1558,1559],{"class":80}," };  ",[37,1561,1562],{"class":43},"\u002F\u002F fallback for user\n",[37,1564,1565],{"class":39,"line":507},[37,1566,499],{"class":80},[37,1568,1569],{"class":39,"line":512},[37,1570,63],{"emptyLinePlaceholder":62},[37,1572,1573,1575],{"class":39,"line":518},[37,1574,1514],{"class":69},[37,1576,1577],{"class":80}," posts;\n",[37,1579,1580,1582],{"class":39,"line":539},[37,1581,371],{"class":69},[37,1583,374],{"class":80},[37,1585,1586,1589,1591,1593,1595],{"class":39,"line":559},[37,1587,1588],{"class":80},"        posts ",[37,1590,721],{"class":69},[37,1592,206],{"class":69},[37,1594,1416],{"class":76},[37,1596,1597],{"class":80},"(user);\n",[37,1599,1600,1602,1604],{"class":39,"line":1093},[37,1601,469],{"class":80},[37,1603,472],{"class":69},[37,1605,374],{"class":80},[37,1607,1608,1610,1612,1615],{"class":39,"line":1110},[37,1609,1588],{"class":80},[37,1611,721],{"class":69},[37,1613,1614],{"class":80}," [];  ",[37,1616,1617],{"class":43},"\u002F\u002F fallback for posts\n",[37,1619,1620],{"class":39,"line":1115},[37,1621,499],{"class":80},[37,1623,1624],{"class":39,"line":1130},[37,1625,63],{"emptyLinePlaceholder":62},[37,1627,1628,1630],{"class":39,"line":1139},[37,1629,250],{"class":69},[37,1631,1632],{"class":80}," { user, posts };\n",[37,1634,1635],{"class":39,"line":1153},[37,1636,259],{"class":80},[37,1638,1640],{"class":39,"line":1639},50,[37,1641,63],{"emptyLinePlaceholder":62},[37,1643,1645],{"class":39,"line":1644},51,[37,1646,1647],{"class":43},"\u002F\u002F ── finally with async\u002Fawait ──\n",[37,1649,1651,1653,1655,1658],{"class":39,"line":1650},52,[37,1652,70],{"class":69},[37,1654,73],{"class":69},[37,1656,1657],{"class":76}," withCleanup",[37,1659,191],{"class":80},[37,1661,1663,1665,1668,1670,1672,1675],{"class":39,"line":1662},53,[37,1664,197],{"class":69},[37,1666,1667],{"class":87}," resource",[37,1669,203],{"class":69},[37,1671,206],{"class":69},[37,1673,1674],{"class":76}," acquireResource",[37,1676,1136],{"class":80},[37,1678,1680,1682],{"class":39,"line":1679},54,[37,1681,371],{"class":69},[37,1683,374],{"class":80},[37,1685,1687,1689,1691,1694],{"class":39,"line":1686},55,[37,1688,1251],{"class":69},[37,1690,206],{"class":69},[37,1692,1693],{"class":76}," useResource",[37,1695,1696],{"class":80},"(resource);\n",[37,1698,1700,1702,1705],{"class":39,"line":1699},56,[37,1701,469],{"class":80},[37,1703,1704],{"class":69},"finally",[37,1706,374],{"class":80},[37,1708,1710,1713,1716,1719],{"class":39,"line":1709},57,[37,1711,1712],{"class":69},"        await",[37,1714,1715],{"class":76}," releaseResource",[37,1717,1718],{"class":80},"(resource);  ",[37,1720,1721],{"class":43},"\u002F\u002F runs on both success and error\n",[37,1723,1725],{"class":39,"line":1724},58,[37,1726,499],{"class":80},[37,1728,1730],{"class":39,"line":1729},59,[37,1731,259],{"class":80},[15,1733,1735,1736,1739],{"id":1734},"anti-pattern-await-in-a-loop-sequential-when-you-want-concurrent","Anti-Pattern: ",[20,1737,1738],{},"await"," in a Loop (Sequential When You Want Concurrent)",[25,1741,1742],{"language":27},[29,1743,1745],{"className":31,"code":1744,"language":27,"meta":33,"style":33},"\u002F\u002F ❌ NAIVE — await in a loop (sequential — slow!)\nasync function fetchAll(urls) {\n    const results = [];\n    for (const url of urls) {\n        results.push(await fetch(url).then(r => r.json()));  \u002F\u002F waits for each, one at a time\n    }\n    return results;  \u002F\u002F total time: sum of all requests (very slow for many URLs)\n}\n\n\u002F\u002F ✅ CORRECT — Promise.all for concurrent execution\nasync function fetchAllConcurrent(urls) {\n    const promises = urls.map(url => fetch(url).then(r => r.json()));  \u002F\u002F start all immediately\n    return Promise.all(promises);  \u002F\u002F wait for all (total: max time)\n}\n\n\u002F\u002F ✅ ALSO CORRECT — for loops that MUST be sequential (each depends on the previous)\nasync function processSequentially(items) {\n    const results = [];\n    for (const item of items) {\n        \u002F\u002F Must wait for each because the next depends on the previous result\n        const processed = await processItem(item, results.at(-1));\n        results.push(processed);\n    }\n    return results;\n}\n\n\u002F\u002F ✅ LIMITED CONCURRENCY — process in batches (avoid overwhelming the server)\nasync function fetchInBatches(urls, batchSize = 5) {\n    const results = [];\n    for (let i = 0; i \u003C urls.length; i += batchSize) {\n        const batch = urls.slice(i, i + batchSize);\n        const batchResults = await Promise.all(\n            batch.map(url => fetch(url).then(r => r.json()))\n        );\n        results.push(...batchResults);\n    }\n    return results;\n}\n",[20,1746,1747,1752,1768,1780,1798,1833,1837,1847,1851,1855,1860,1875,1918,1934,1938,1942,1947,1963,1973,1989,1994,2025,2034,2038,2045,2049,2053,2058,2083,2093,2129,2152,2172,2204,2209,2223,2227,2233],{"__ignoreMap":33},[37,1748,1749],{"class":39,"line":40},[37,1750,1751],{"class":43},"\u002F\u002F ❌ NAIVE — await in a loop (sequential — slow!)\n",[37,1753,1754,1756,1758,1761,1763,1766],{"class":39,"line":47},[37,1755,70],{"class":69},[37,1757,73],{"class":69},[37,1759,1760],{"class":76}," fetchAll",[37,1762,132],{"class":80},[37,1764,1765],{"class":309},"urls",[37,1767,1284],{"class":80},[37,1769,1770,1772,1775,1777],{"class":39,"line":53},[37,1771,197],{"class":69},[37,1773,1774],{"class":87}," results",[37,1776,203],{"class":69},[37,1778,1779],{"class":80}," [];\n",[37,1781,1782,1785,1787,1789,1792,1795],{"class":39,"line":59},[37,1783,1784],{"class":69},"    for",[37,1786,1218],{"class":80},[37,1788,521],{"class":69},[37,1790,1791],{"class":87}," url",[37,1793,1794],{"class":69}," of",[37,1796,1797],{"class":80}," urls) {\n",[37,1799,1800,1803,1806,1808,1810,1812,1815,1817,1819,1821,1823,1825,1827,1830],{"class":39,"line":66},[37,1801,1802],{"class":80},"        results.",[37,1804,1805],{"class":76},"push",[37,1807,132],{"class":80},[37,1809,1738],{"class":69},[37,1811,209],{"class":76},[37,1813,1814],{"class":80},"(url).",[37,1816,304],{"class":76},[37,1818,132],{"class":80},[37,1820,846],{"class":309},[37,1822,313],{"class":69},[37,1824,851],{"class":80},[37,1826,238],{"class":76},[37,1828,1829],{"class":80},"()));  ",[37,1831,1832],{"class":43},"\u002F\u002F waits for each, one at a time\n",[37,1834,1835],{"class":39,"line":94},[37,1836,499],{"class":80},[37,1838,1839,1841,1844],{"class":39,"line":106},[37,1840,250],{"class":69},[37,1842,1843],{"class":80}," results;  ",[37,1845,1846],{"class":43},"\u002F\u002F total time: sum of all requests (very slow for many URLs)\n",[37,1848,1849],{"class":39,"line":111},[37,1850,259],{"class":80},[37,1852,1853],{"class":39,"line":142},[37,1854,63],{"emptyLinePlaceholder":62},[37,1856,1857],{"class":39,"line":153},[37,1858,1859],{"class":43},"\u002F\u002F ✅ CORRECT — Promise.all for concurrent execution\n",[37,1861,1862,1864,1866,1869,1871,1873],{"class":39,"line":158},[37,1863,70],{"class":69},[37,1865,73],{"class":69},[37,1867,1868],{"class":76}," fetchAllConcurrent",[37,1870,132],{"class":80},[37,1872,1765],{"class":309},[37,1874,1284],{"class":80},[37,1876,1877,1879,1882,1884,1887,1890,1892,1895,1897,1899,1901,1903,1905,1907,1909,1911,1913,1915],{"class":39,"line":164},[37,1878,197],{"class":69},[37,1880,1881],{"class":87}," promises",[37,1883,203],{"class":69},[37,1885,1886],{"class":80}," urls.",[37,1888,1889],{"class":76},"map",[37,1891,132],{"class":80},[37,1893,1894],{"class":309},"url",[37,1896,313],{"class":69},[37,1898,209],{"class":76},[37,1900,1814],{"class":80},[37,1902,304],{"class":76},[37,1904,132],{"class":80},[37,1906,846],{"class":309},[37,1908,313],{"class":69},[37,1910,851],{"class":80},[37,1912,238],{"class":76},[37,1914,1829],{"class":80},[37,1916,1917],{"class":43},"\u002F\u002F start all immediately\n",[37,1919,1920,1922,1924,1926,1928,1931],{"class":39,"line":170},[37,1921,250],{"class":69},[37,1923,390],{"class":87},[37,1925,393],{"class":80},[37,1927,730],{"class":76},[37,1929,1930],{"class":80},"(promises);  ",[37,1932,1933],{"class":43},"\u002F\u002F wait for all (total: max time)\n",[37,1935,1936],{"class":39,"line":175},[37,1937,259],{"class":80},[37,1939,1940],{"class":39,"line":181},[37,1941,63],{"emptyLinePlaceholder":62},[37,1943,1944],{"class":39,"line":194},[37,1945,1946],{"class":43},"\u002F\u002F ✅ ALSO CORRECT — for loops that MUST be sequential (each depends on the previous)\n",[37,1948,1949,1951,1953,1956,1958,1961],{"class":39,"line":223},[37,1950,70],{"class":69},[37,1952,73],{"class":69},[37,1954,1955],{"class":76}," processSequentially",[37,1957,132],{"class":80},[37,1959,1960],{"class":309},"items",[37,1962,1284],{"class":80},[37,1964,1965,1967,1969,1971],{"class":39,"line":247},[37,1966,197],{"class":69},[37,1968,1774],{"class":87},[37,1970,203],{"class":69},[37,1972,1779],{"class":80},[37,1974,1975,1977,1979,1981,1984,1986],{"class":39,"line":256},[37,1976,1784],{"class":69},[37,1978,1218],{"class":80},[37,1980,521],{"class":69},[37,1982,1983],{"class":87}," item",[37,1985,1794],{"class":69},[37,1987,1988],{"class":80}," items) {\n",[37,1990,1991],{"class":39,"line":262},[37,1992,1993],{"class":43},"        \u002F\u002F Must wait for each because the next depends on the previous result\n",[37,1995,1996,1998,2001,2003,2005,2008,2011,2014,2016,2019,2022],{"class":39,"line":267},[37,1997,380],{"class":69},[37,1999,2000],{"class":87}," processed",[37,2002,203],{"class":69},[37,2004,206],{"class":69},[37,2006,2007],{"class":76}," processItem",[37,2009,2010],{"class":80},"(item, results.",[37,2012,2013],{"class":76},"at",[37,2015,132],{"class":80},[37,2017,2018],{"class":69},"-",[37,2020,2021],{"class":87},"1",[37,2023,2024],{"class":80},"));\n",[37,2026,2027,2029,2031],{"class":39,"line":273},[37,2028,1802],{"class":80},[37,2030,1805],{"class":76},[37,2032,2033],{"class":80},"(processed);\n",[37,2035,2036],{"class":39,"line":284},[37,2037,499],{"class":80},[37,2039,2040,2042],{"class":39,"line":298},[37,2041,250],{"class":69},[37,2043,2044],{"class":80}," results;\n",[37,2046,2047],{"class":39,"line":323},[37,2048,259],{"class":80},[37,2050,2051],{"class":39,"line":340},[37,2052,63],{"emptyLinePlaceholder":62},[37,2054,2055],{"class":39,"line":345},[37,2056,2057],{"class":43},"\u002F\u002F ✅ LIMITED CONCURRENCY — process in batches (avoid overwhelming the server)\n",[37,2059,2060,2062,2064,2067,2069,2071,2073,2076,2078,2081],{"class":39,"line":350},[37,2061,70],{"class":69},[37,2063,73],{"class":69},[37,2065,2066],{"class":76}," fetchInBatches",[37,2068,132],{"class":80},[37,2070,1765],{"class":309},[37,2072,707],{"class":80},[37,2074,2075],{"class":309},"batchSize",[37,2077,203],{"class":69},[37,2079,2080],{"class":87}," 5",[37,2082,1284],{"class":80},[37,2084,2085,2087,2089,2091],{"class":39,"line":356},[37,2086,197],{"class":69},[37,2088,1774],{"class":87},[37,2090,203],{"class":69},[37,2092,1779],{"class":80},[37,2094,2095,2097,2099,2102,2105,2107,2110,2113,2116,2118,2121,2123,2126],{"class":39,"line":368},[37,2096,1784],{"class":69},[37,2098,1218],{"class":80},[37,2100,2101],{"class":69},"let",[37,2103,2104],{"class":80}," i ",[37,2106,721],{"class":69},[37,2108,2109],{"class":87}," 0",[37,2111,2112],{"class":80},"; i ",[37,2114,2115],{"class":69},"\u003C",[37,2117,1886],{"class":80},[37,2119,2120],{"class":87},"length",[37,2122,2112],{"class":80},[37,2124,2125],{"class":69},"+=",[37,2127,2128],{"class":80}," batchSize) {\n",[37,2130,2131,2133,2136,2138,2140,2143,2146,2149],{"class":39,"line":377},[37,2132,380],{"class":69},[37,2134,2135],{"class":87}," batch",[37,2137,203],{"class":69},[37,2139,1886],{"class":80},[37,2141,2142],{"class":76},"slice",[37,2144,2145],{"class":80},"(i, i ",[37,2147,2148],{"class":69},"+",[37,2150,2151],{"class":80}," batchSize);\n",[37,2153,2154,2156,2159,2161,2163,2165,2167,2169],{"class":39,"line":409},[37,2155,380],{"class":69},[37,2157,2158],{"class":87}," batchResults",[37,2160,203],{"class":69},[37,2162,206],{"class":69},[37,2164,390],{"class":87},[37,2166,393],{"class":80},[37,2168,730],{"class":76},[37,2170,2171],{"class":80},"(\n",[37,2173,2174,2177,2179,2181,2183,2185,2187,2189,2191,2193,2195,2197,2199,2201],{"class":39,"line":424},[37,2175,2176],{"class":80},"            batch.",[37,2178,1889],{"class":76},[37,2180,132],{"class":80},[37,2182,1894],{"class":309},[37,2184,313],{"class":69},[37,2186,209],{"class":76},[37,2188,1814],{"class":80},[37,2190,304],{"class":76},[37,2192,132],{"class":80},[37,2194,846],{"class":309},[37,2196,313],{"class":69},[37,2198,851],{"class":80},[37,2200,238],{"class":76},[37,2202,2203],{"class":80},"()))\n",[37,2205,2206],{"class":39,"line":429},[37,2207,2208],{"class":80},"        );\n",[37,2210,2211,2213,2215,2217,2220],{"class":39,"line":466},[37,2212,1802],{"class":80},[37,2214,1805],{"class":76},[37,2216,132],{"class":80},[37,2218,2219],{"class":69},"...",[37,2221,2222],{"class":80},"batchResults);\n",[37,2224,2225],{"class":39,"line":478},[37,2226,499],{"class":80},[37,2228,2229,2231],{"class":39,"line":496},[37,2230,250],{"class":69},[37,2232,2044],{"class":80},[37,2234,2235],{"class":39,"line":502},[37,2236,259],{"class":80},[15,2238,2240],{"id":2239},"top-level-await-es2022","Top-Level Await (ES2022)",[25,2242,2243],{"language":27},[29,2244,2246],{"className":31,"code":2245,"language":27,"meta":33,"style":33},"\u002F\u002F ── Top-level await: use await outside an async function (ESM only) ──\n\u002F\u002F Only in ES Modules (not CommonJS, not scripts without type:module)\n\n\u002F\u002F config.js (ESM):\n\u002F\u002F const response = await fetch(\"\u002Fconfig.json\");\n\u002F\u002F const config = await response.json();\n\u002F\u002F export default config;\n\n\u002F\u002F ⚠️ Top-level await blocks all modules that import this one:\n\u002F\u002F If another module imports config.js, it waits for the fetch to complete.\n\u002F\u002F This can slow down the entire module graph.\n\u002F\u002F Use sparingly — prefer dynamic import for lazy loading.\n\n\u002F\u002F ── Workaround for non-ESM (IIFE wrapper) ──\n\u002F\u002F In CJS or browser scripts (no top-level await):\n(async () => {\n    const config = await fetch(\"\u002Fconfig.json\").then(r => r.json());\n    initApp(config);\n})();  \u002F\u002F async IIFE — runs immediately, doesn't block\n\n\u002F\u002F ── Common top-level await pattern: initialize before export ──\n\u002F\u002F db.js:\nlet db;\nconst dbPromise = initDatabase().then(connection => { db = connection; });\nawait dbPromise;  \u002F\u002F top-level await — blocks importers until DB is ready\nexport { db };\n\n\u002F\u002F app.js:\n\u002F\u002F import { db } from \".\u002Fdb.js\";  \u002F\u002F waits for db.js to finish (db is initialized)\n",[20,2247,2248,2253,2258,2262,2267,2272,2277,2282,2286,2291,2296,2301,2306,2310,2315,2320,2334,2368,2376,2384,2388,2393,2398,2405,2437,2447,2455,2459,2464],{"__ignoreMap":33},[37,2249,2250],{"class":39,"line":40},[37,2251,2252],{"class":43},"\u002F\u002F ── Top-level await: use await outside an async function (ESM only) ──\n",[37,2254,2255],{"class":39,"line":47},[37,2256,2257],{"class":43},"\u002F\u002F Only in ES Modules (not CommonJS, not scripts without type:module)\n",[37,2259,2260],{"class":39,"line":53},[37,2261,63],{"emptyLinePlaceholder":62},[37,2263,2264],{"class":39,"line":59},[37,2265,2266],{"class":43},"\u002F\u002F config.js (ESM):\n",[37,2268,2269],{"class":39,"line":66},[37,2270,2271],{"class":43},"\u002F\u002F const response = await fetch(\"\u002Fconfig.json\");\n",[37,2273,2274],{"class":39,"line":94},[37,2275,2276],{"class":43},"\u002F\u002F const config = await response.json();\n",[37,2278,2279],{"class":39,"line":106},[37,2280,2281],{"class":43},"\u002F\u002F export default config;\n",[37,2283,2284],{"class":39,"line":111},[37,2285,63],{"emptyLinePlaceholder":62},[37,2287,2288],{"class":39,"line":142},[37,2289,2290],{"class":43},"\u002F\u002F ⚠️ Top-level await blocks all modules that import this one:\n",[37,2292,2293],{"class":39,"line":153},[37,2294,2295],{"class":43},"\u002F\u002F If another module imports config.js, it waits for the fetch to complete.\n",[37,2297,2298],{"class":39,"line":158},[37,2299,2300],{"class":43},"\u002F\u002F This can slow down the entire module graph.\n",[37,2302,2303],{"class":39,"line":164},[37,2304,2305],{"class":43},"\u002F\u002F Use sparingly — prefer dynamic import for lazy loading.\n",[37,2307,2308],{"class":39,"line":170},[37,2309,63],{"emptyLinePlaceholder":62},[37,2311,2312],{"class":39,"line":175},[37,2313,2314],{"class":43},"\u002F\u002F ── Workaround for non-ESM (IIFE wrapper) ──\n",[37,2316,2317],{"class":39,"line":181},[37,2318,2319],{"class":43},"\u002F\u002F In CJS or browser scripts (no top-level await):\n",[37,2321,2322,2324,2326,2329,2332],{"class":39,"line":194},[37,2323,132],{"class":80},[37,2325,70],{"class":69},[37,2327,2328],{"class":80}," () ",[37,2330,2331],{"class":69},"=>",[37,2333,374],{"class":80},[37,2335,2336,2338,2341,2343,2345,2347,2349,2352,2354,2356,2358,2360,2362,2364,2366],{"class":39,"line":223},[37,2337,197],{"class":69},[37,2339,2340],{"class":87}," config",[37,2342,203],{"class":69},[37,2344,206],{"class":69},[37,2346,209],{"class":76},[37,2348,132],{"class":80},[37,2350,2351],{"class":135},"\"\u002Fconfig.json\"",[37,2353,839],{"class":80},[37,2355,304],{"class":76},[37,2357,132],{"class":80},[37,2359,846],{"class":309},[37,2361,313],{"class":69},[37,2363,851],{"class":80},[37,2365,238],{"class":76},[37,2367,856],{"class":80},[37,2369,2370,2373],{"class":39,"line":247},[37,2371,2372],{"class":76},"    initApp",[37,2374,2375],{"class":80},"(config);\n",[37,2377,2378,2381],{"class":39,"line":256},[37,2379,2380],{"class":80},"})();  ",[37,2382,2383],{"class":43},"\u002F\u002F async IIFE — runs immediately, doesn't block\n",[37,2385,2386],{"class":39,"line":262},[37,2387,63],{"emptyLinePlaceholder":62},[37,2389,2390],{"class":39,"line":267},[37,2391,2392],{"class":43},"\u002F\u002F ── Common top-level await pattern: initialize before export ──\n",[37,2394,2395],{"class":39,"line":273},[37,2396,2397],{"class":43},"\u002F\u002F db.js:\n",[37,2399,2400,2402],{"class":39,"line":284},[37,2401,2101],{"class":69},[37,2403,2404],{"class":80}," db;\n",[37,2406,2407,2409,2412,2414,2417,2420,2422,2424,2427,2429,2432,2434],{"class":39,"line":298},[37,2408,521],{"class":69},[37,2410,2411],{"class":87}," dbPromise",[37,2413,203],{"class":69},[37,2415,2416],{"class":76}," initDatabase",[37,2418,2419],{"class":80},"().",[37,2421,304],{"class":76},[37,2423,132],{"class":80},[37,2425,2426],{"class":309},"connection",[37,2428,313],{"class":69},[37,2430,2431],{"class":80}," { db ",[37,2433,721],{"class":69},[37,2435,2436],{"class":80}," connection; });\n",[37,2438,2439,2441,2444],{"class":39,"line":323},[37,2440,1738],{"class":69},[37,2442,2443],{"class":80}," dbPromise;  ",[37,2445,2446],{"class":43},"\u002F\u002F top-level await — blocks importers until DB is ready\n",[37,2448,2449,2452],{"class":39,"line":340},[37,2450,2451],{"class":69},"export",[37,2453,2454],{"class":80}," { db };\n",[37,2456,2457],{"class":39,"line":345},[37,2458,63],{"emptyLinePlaceholder":62},[37,2460,2461],{"class":39,"line":350},[37,2462,2463],{"class":43},"\u002F\u002F app.js:\n",[37,2465,2466,2469],{"class":39,"line":356},[37,2467,2468],{"class":43},"\u002F\u002F import { db } from \".\u002Fdb.js\";",[37,2470,2471],{"class":43},"  \u002F\u002F waits for db.js to finish (db is initialized)\n",[15,2473,2475],{"id":2474},"production-pattern-async-iterator","Production Pattern: Async Iterator",[25,2477,2478],{"language":27},[29,2479,2481],{"className":31,"code":2480,"language":27,"meta":33,"style":33},"\u002F\u002F ── for await...of: iterate over async iterables (streams, paginated APIs) ──\nasync function* paginate(url) {\n    let page = 1;\n    while (true) {\n        const response = await fetch(`${url}?page=${page}`);\n        const data = await response.json();\n        if (data.length === 0) break;  \u002F\u002F no more pages\n        yield* data;  \u002F\u002F yield each item from the page\n        page++;\n    }\n}\n\n\u002F\u002F Consume with for await...of:\nfor await (const item of paginate(\"\u002Fapi\u002Fitems\")) {\n    console.log(item);  \u002F\u002F process each item as it arrives\n}\n\n\u002F\u002F ── Async generator for a stream ──\nasync function* readLines(stream) {\n    const reader = stream.getReader();\n    const decoder = new TextDecoder();\n    let buffer = \"\";\n    while (true) {\n        const { done, value } = await reader.read();\n        if (done) break;\n        buffer += decoder.decode(value, { stream: true });\n        const lines = buffer.split(\"\\n\");\n        buffer = lines.pop();  \u002F\u002F keep the last partial line in the buffer\n        for (const line of lines) yield line;\n    }\n    if (buffer) yield buffer;  \u002F\u002F yield the last line\n}\n\n\u002F\u002F Consume a fetch response line by line:\nconst response = await fetch(\"\u002Fapi\u002Fstream\");\nfor await (const line of readLines(response.body)) {\n    console.log(\"line:\", line);\n}\n",[20,2482,2483,2488,2504,2519,2531,2560,2576,2601,2612,2622,2626,2630,2634,2639,2664,2676,2680,2684,2689,2705,2722,2738,2752,2762,2792,2803,2824,2851,2868,2891,2895,2911,2915,2919,2924,2943,2962,2976],{"__ignoreMap":33},[37,2484,2485],{"class":39,"line":40},[37,2486,2487],{"class":43},"\u002F\u002F ── for await...of: iterate over async iterables (streams, paginated APIs) ──\n",[37,2489,2490,2492,2495,2498,2500,2502],{"class":39,"line":47},[37,2491,70],{"class":69},[37,2493,2494],{"class":69}," function*",[37,2496,2497],{"class":76}," paginate",[37,2499,132],{"class":80},[37,2501,1894],{"class":309},[37,2503,1284],{"class":80},[37,2505,2506,2508,2511,2513,2516],{"class":39,"line":53},[37,2507,1514],{"class":69},[37,2509,2510],{"class":80}," page ",[37,2512,721],{"class":69},[37,2514,2515],{"class":87}," 1",[37,2517,2518],{"class":80},";\n",[37,2520,2521,2524,2526,2529],{"class":39,"line":59},[37,2522,2523],{"class":69},"    while",[37,2525,1218],{"class":80},[37,2527,2528],{"class":87},"true",[37,2530,1284],{"class":80},[37,2532,2533,2535,2537,2539,2541,2543,2545,2548,2550,2553,2556,2558],{"class":39,"line":66},[37,2534,380],{"class":69},[37,2536,200],{"class":87},[37,2538,203],{"class":69},[37,2540,206],{"class":69},[37,2542,209],{"class":76},[37,2544,132],{"class":80},[37,2546,2547],{"class":135},"`${",[37,2549,1894],{"class":80},[37,2551,2552],{"class":135},"}?page=${",[37,2554,2555],{"class":80},"page",[37,2557,909],{"class":135},[37,2559,1075],{"class":80},[37,2561,2562,2564,2566,2568,2570,2572,2574],{"class":39,"line":94},[37,2563,380],{"class":69},[37,2565,228],{"class":87},[37,2567,203],{"class":69},[37,2569,206],{"class":69},[37,2571,235],{"class":80},[37,2573,238],{"class":76},[37,2575,1136],{"class":80},[37,2577,2578,2580,2583,2585,2588,2590,2593,2596,2598],{"class":39,"line":106},[37,2579,1215],{"class":69},[37,2581,2582],{"class":80}," (data.",[37,2584,2120],{"class":87},[37,2586,2587],{"class":69}," ===",[37,2589,2109],{"class":87},[37,2591,2592],{"class":80},") ",[37,2594,2595],{"class":69},"break",[37,2597,533],{"class":80},[37,2599,2600],{"class":43},"\u002F\u002F no more pages\n",[37,2602,2603,2606,2609],{"class":39,"line":111},[37,2604,2605],{"class":69},"        yield*",[37,2607,2608],{"class":80}," data;  ",[37,2610,2611],{"class":43},"\u002F\u002F yield each item from the page\n",[37,2613,2614,2617,2620],{"class":39,"line":142},[37,2615,2616],{"class":80},"        page",[37,2618,2619],{"class":69},"++",[37,2621,2518],{"class":80},[37,2623,2624],{"class":39,"line":153},[37,2625,499],{"class":80},[37,2627,2628],{"class":39,"line":158},[37,2629,259],{"class":80},[37,2631,2632],{"class":39,"line":164},[37,2633,63],{"emptyLinePlaceholder":62},[37,2635,2636],{"class":39,"line":170},[37,2637,2638],{"class":43},"\u002F\u002F Consume with for await...of:\n",[37,2640,2641,2644,2646,2648,2650,2652,2654,2656,2658,2661],{"class":39,"line":175},[37,2642,2643],{"class":69},"for",[37,2645,206],{"class":69},[37,2647,1218],{"class":80},[37,2649,521],{"class":69},[37,2651,1983],{"class":87},[37,2653,1794],{"class":69},[37,2655,2497],{"class":76},[37,2657,132],{"class":80},[37,2659,2660],{"class":135},"\"\u002Fapi\u002Fitems\"",[37,2662,2663],{"class":80},")) {\n",[37,2665,2666,2668,2670,2673],{"class":39,"line":181},[37,2667,1065],{"class":80},[37,2669,415],{"class":76},[37,2671,2672],{"class":80},"(item);  ",[37,2674,2675],{"class":43},"\u002F\u002F process each item as it arrives\n",[37,2677,2678],{"class":39,"line":194},[37,2679,259],{"class":80},[37,2681,2682],{"class":39,"line":223},[37,2683,63],{"emptyLinePlaceholder":62},[37,2685,2686],{"class":39,"line":247},[37,2687,2688],{"class":43},"\u002F\u002F ── Async generator for a stream ──\n",[37,2690,2691,2693,2695,2698,2700,2703],{"class":39,"line":256},[37,2692,70],{"class":69},[37,2694,2494],{"class":69},[37,2696,2697],{"class":76}," readLines",[37,2699,132],{"class":80},[37,2701,2702],{"class":309},"stream",[37,2704,1284],{"class":80},[37,2706,2707,2709,2712,2714,2717,2720],{"class":39,"line":262},[37,2708,197],{"class":69},[37,2710,2711],{"class":87}," reader",[37,2713,203],{"class":69},[37,2715,2716],{"class":80}," stream.",[37,2718,2719],{"class":76},"getReader",[37,2721,1136],{"class":80},[37,2723,2724,2726,2729,2731,2733,2736],{"class":39,"line":267},[37,2725,197],{"class":69},[37,2727,2728],{"class":87}," decoder",[37,2730,203],{"class":69},[37,2732,126],{"class":69},[37,2734,2735],{"class":76}," TextDecoder",[37,2737,1136],{"class":80},[37,2739,2740,2742,2745,2747,2750],{"class":39,"line":273},[37,2741,1514],{"class":69},[37,2743,2744],{"class":80}," buffer ",[37,2746,721],{"class":69},[37,2748,2749],{"class":135}," \"\"",[37,2751,2518],{"class":80},[37,2753,2754,2756,2758,2760],{"class":39,"line":284},[37,2755,2523],{"class":69},[37,2757,1218],{"class":80},[37,2759,2528],{"class":87},[37,2761,1284],{"class":80},[37,2763,2764,2766,2769,2772,2774,2777,2780,2782,2784,2787,2790],{"class":39,"line":298},[37,2765,380],{"class":69},[37,2767,2768],{"class":80}," { ",[37,2770,2771],{"class":87},"done",[37,2773,707],{"class":80},[37,2775,2776],{"class":87},"value",[37,2778,2779],{"class":80}," } ",[37,2781,721],{"class":69},[37,2783,206],{"class":69},[37,2785,2786],{"class":80}," reader.",[37,2788,2789],{"class":76},"read",[37,2791,1136],{"class":80},[37,2793,2794,2796,2799,2801],{"class":39,"line":323},[37,2795,1215],{"class":69},[37,2797,2798],{"class":80}," (done) ",[37,2800,2595],{"class":69},[37,2802,2518],{"class":80},[37,2804,2805,2808,2810,2813,2816,2819,2821],{"class":39,"line":340},[37,2806,2807],{"class":80},"        buffer ",[37,2809,2125],{"class":69},[37,2811,2812],{"class":80}," decoder.",[37,2814,2815],{"class":76},"decode",[37,2817,2818],{"class":80},"(value, { stream: ",[37,2820,2528],{"class":87},[37,2822,2823],{"class":80}," });\n",[37,2825,2826,2828,2831,2833,2836,2839,2841,2844,2847,2849],{"class":39,"line":345},[37,2827,380],{"class":69},[37,2829,2830],{"class":87}," lines",[37,2832,203],{"class":69},[37,2834,2835],{"class":80}," buffer.",[37,2837,2838],{"class":76},"split",[37,2840,132],{"class":80},[37,2842,2843],{"class":135},"\"",[37,2845,2846],{"class":87},"\\n",[37,2848,2843],{"class":135},[37,2850,1075],{"class":80},[37,2852,2853,2855,2857,2860,2863,2865],{"class":39,"line":350},[37,2854,2807],{"class":80},[37,2856,721],{"class":69},[37,2858,2859],{"class":80}," lines.",[37,2861,2862],{"class":76},"pop",[37,2864,100],{"class":80},[37,2866,2867],{"class":43},"\u002F\u002F keep the last partial line in the buffer\n",[37,2869,2870,2873,2875,2877,2880,2882,2885,2888],{"class":39,"line":356},[37,2871,2872],{"class":69},"        for",[37,2874,1218],{"class":80},[37,2876,521],{"class":69},[37,2878,2879],{"class":87}," line",[37,2881,1794],{"class":69},[37,2883,2884],{"class":80}," lines) ",[37,2886,2887],{"class":69},"yield",[37,2889,2890],{"class":80}," line;\n",[37,2892,2893],{"class":39,"line":368},[37,2894,499],{"class":80},[37,2896,2897,2900,2903,2905,2908],{"class":39,"line":377},[37,2898,2899],{"class":69},"    if",[37,2901,2902],{"class":80}," (buffer) ",[37,2904,2887],{"class":69},[37,2906,2907],{"class":80}," buffer;  ",[37,2909,2910],{"class":43},"\u002F\u002F yield the last line\n",[37,2912,2913],{"class":39,"line":409},[37,2914,259],{"class":80},[37,2916,2917],{"class":39,"line":424},[37,2918,63],{"emptyLinePlaceholder":62},[37,2920,2921],{"class":39,"line":429},[37,2922,2923],{"class":43},"\u002F\u002F Consume a fetch response line by line:\n",[37,2925,2926,2928,2930,2932,2934,2936,2938,2941],{"class":39,"line":466},[37,2927,521],{"class":69},[37,2929,200],{"class":87},[37,2931,203],{"class":69},[37,2933,206],{"class":69},[37,2935,209],{"class":76},[37,2937,132],{"class":80},[37,2939,2940],{"class":135},"\"\u002Fapi\u002Fstream\"",[37,2942,1075],{"class":80},[37,2944,2945,2947,2949,2951,2953,2955,2957,2959],{"class":39,"line":478},[37,2946,2643],{"class":69},[37,2948,206],{"class":69},[37,2950,1218],{"class":80},[37,2952,521],{"class":69},[37,2954,2879],{"class":87},[37,2956,1794],{"class":69},[37,2958,2697],{"class":76},[37,2960,2961],{"class":80},"(response.body)) {\n",[37,2963,2964,2966,2968,2970,2973],{"class":39,"line":496},[37,2965,1065],{"class":80},[37,2967,415],{"class":76},[37,2969,132],{"class":80},[37,2971,2972],{"class":135},"\"line:\"",[37,2974,2975],{"class":80},", line);\n",[37,2977,2978],{"class":39,"line":502},[37,2979,259],{"class":80},[15,2981,2983],{"id":2982},"tips-tricks","💡 Tips & Tricks",[25,2985,2986],{"language":27},[29,2987,2989],{"className":31,"code":2988,"language":27,"meta":33,"style":33},"\u002F\u002F ── `await` on a non-Promise (wraps in Promise.resolve) ──\nconst value = await 42;  \u002F\u002F Promise.resolve(42) → 42 (effectively synchronous but yields once)\n\n\u002F\u002F ── `Promise.all` with map (concurrent mapping) ──\nconst results = await Promise.all(items.map(async item => {\n    return await processItem(item);  \u002F\u002F all items processed concurrently\n}));\n\n\u002F\u002F ── `Promise.allSettled` for \"try all, report failures\" ──\nconst results = await Promise.allSettled(items.map(item => processItem(item)));\nresults.forEach((r, i) => {\n    if (r.status === \"fulfilled\") console.log(`item ${i}: ok`);\n    else console.log(`item ${i}: failed -`, r.reason.message);\n});\n\n\u002F\u002F ── AbortController for cancellable async ──\nconst controller = new AbortController();\nsetTimeout(() => controller.abort(), 5000);  \u002F\u002F 5s timeout\ntry {\n    const data = await fetch(url, { signal: controller.signal });\n} catch (err) {\n    if (err.name === \"AbortError\") console.log(\"cancelled\");\n}\n\n\u002F\u002F ── `await` in any expression (not just statements) ──\nconst result = (await getData()).filter(x => x.active).map(x => x.name);\n\u002F\u002F ⚠️ await has lower precedence than .filter\u002F.map — it waits for getData() first,\n\u002F\u002F then the chain runs on the result. Wrap in parens if needed: await (getData().then(...)).\n\n\u002F\u002F ── `async` arrow functions ──\nconst asyncArrow = async (x) => { return await fetch(`\u002F${x}`); };\nconst asyncArrow2 = async (x) => fetch(`\u002F${x}`);  \u002F\u002F fetch returns a Promise → await is optional\n",[20,2990,2991,2996,3013,3017,3022,3053,3066,3071,3075,3080,3113,3137,3167,3189,3194,3198,3203,3219,3246,3253,3268,3278,3301,3305,3309,3314,3356,3361,3366,3370,3375,3415],{"__ignoreMap":33},[37,2992,2993],{"class":39,"line":40},[37,2994,2995],{"class":43},"\u002F\u002F ── `await` on a non-Promise (wraps in Promise.resolve) ──\n",[37,2997,2998,3000,3002,3004,3006,3008,3010],{"class":39,"line":47},[37,2999,521],{"class":69},[37,3001,383],{"class":87},[37,3003,203],{"class":69},[37,3005,206],{"class":69},[37,3007,88],{"class":87},[37,3009,533],{"class":80},[37,3011,3012],{"class":43},"\u002F\u002F Promise.resolve(42) → 42 (effectively synchronous but yields once)\n",[37,3014,3015],{"class":39,"line":53},[37,3016,63],{"emptyLinePlaceholder":62},[37,3018,3019],{"class":39,"line":59},[37,3020,3021],{"class":43},"\u002F\u002F ── `Promise.all` with map (concurrent mapping) ──\n",[37,3023,3024,3026,3028,3030,3032,3034,3036,3038,3041,3043,3045,3047,3049,3051],{"class":39,"line":66},[37,3025,521],{"class":69},[37,3027,1774],{"class":87},[37,3029,203],{"class":69},[37,3031,206],{"class":69},[37,3033,390],{"class":87},[37,3035,393],{"class":80},[37,3037,730],{"class":76},[37,3039,3040],{"class":80},"(items.",[37,3042,1889],{"class":76},[37,3044,132],{"class":80},[37,3046,70],{"class":69},[37,3048,1983],{"class":309},[37,3050,313],{"class":69},[37,3052,374],{"class":80},[37,3054,3055,3057,3059,3061,3063],{"class":39,"line":94},[37,3056,250],{"class":69},[37,3058,206],{"class":69},[37,3060,2007],{"class":76},[37,3062,2672],{"class":80},[37,3064,3065],{"class":43},"\u002F\u002F all items processed concurrently\n",[37,3067,3068],{"class":39,"line":106},[37,3069,3070],{"class":80},"}));\n",[37,3072,3073],{"class":39,"line":111},[37,3074,63],{"emptyLinePlaceholder":62},[37,3076,3077],{"class":39,"line":142},[37,3078,3079],{"class":43},"\u002F\u002F ── `Promise.allSettled` for \"try all, report failures\" ──\n",[37,3081,3082,3084,3086,3088,3090,3092,3094,3097,3099,3101,3103,3106,3108,3110],{"class":39,"line":153},[37,3083,521],{"class":69},[37,3085,1774],{"class":87},[37,3087,203],{"class":69},[37,3089,206],{"class":69},[37,3091,390],{"class":87},[37,3093,393],{"class":80},[37,3095,3096],{"class":76},"allSettled",[37,3098,3040],{"class":80},[37,3100,1889],{"class":76},[37,3102,132],{"class":80},[37,3104,3105],{"class":309},"item",[37,3107,313],{"class":69},[37,3109,2007],{"class":76},[37,3111,3112],{"class":80},"(item)));\n",[37,3114,3115,3118,3121,3124,3126,3128,3131,3133,3135],{"class":39,"line":158},[37,3116,3117],{"class":80},"results.",[37,3119,3120],{"class":76},"forEach",[37,3122,3123],{"class":80},"((",[37,3125,846],{"class":309},[37,3127,707],{"class":80},[37,3129,3130],{"class":309},"i",[37,3132,2592],{"class":80},[37,3134,2331],{"class":69},[37,3136,374],{"class":80},[37,3138,3139,3141,3144,3147,3150,3153,3155,3157,3160,3162,3165],{"class":39,"line":164},[37,3140,2899],{"class":69},[37,3142,3143],{"class":80}," (r.status ",[37,3145,3146],{"class":69},"===",[37,3148,3149],{"class":135}," \"fulfilled\"",[37,3151,3152],{"class":80},") console.",[37,3154,415],{"class":76},[37,3156,132],{"class":80},[37,3158,3159],{"class":135},"`item ${",[37,3161,3130],{"class":80},[37,3163,3164],{"class":135},"}: ok`",[37,3166,1075],{"class":80},[37,3168,3169,3172,3175,3177,3179,3181,3183,3186],{"class":39,"line":170},[37,3170,3171],{"class":69},"    else",[37,3173,3174],{"class":80}," console.",[37,3176,415],{"class":76},[37,3178,132],{"class":80},[37,3180,3159],{"class":135},[37,3182,3130],{"class":80},[37,3184,3185],{"class":135},"}: failed -`",[37,3187,3188],{"class":80},", r.reason.message);\n",[37,3190,3191],{"class":39,"line":175},[37,3192,3193],{"class":80},"});\n",[37,3195,3196],{"class":39,"line":181},[37,3197,63],{"emptyLinePlaceholder":62},[37,3199,3200],{"class":39,"line":194},[37,3201,3202],{"class":43},"\u002F\u002F ── AbortController for cancellable async ──\n",[37,3204,3205,3207,3210,3212,3214,3217],{"class":39,"line":223},[37,3206,521],{"class":69},[37,3208,3209],{"class":87}," controller",[37,3211,203],{"class":69},[37,3213,126],{"class":69},[37,3215,3216],{"class":76}," AbortController",[37,3218,1136],{"class":80},[37,3220,3221,3224,3227,3229,3232,3235,3238,3241,3243],{"class":39,"line":247},[37,3222,3223],{"class":76},"setTimeout",[37,3225,3226],{"class":80},"(() ",[37,3228,2331],{"class":69},[37,3230,3231],{"class":80}," controller.",[37,3233,3234],{"class":76},"abort",[37,3236,3237],{"class":80},"(), ",[37,3239,3240],{"class":87},"5000",[37,3242,217],{"class":80},[37,3244,3245],{"class":43},"\u002F\u002F 5s timeout\n",[37,3247,3248,3251],{"class":39,"line":256},[37,3249,3250],{"class":69},"try",[37,3252,374],{"class":80},[37,3254,3255,3257,3259,3261,3263,3265],{"class":39,"line":262},[37,3256,197],{"class":69},[37,3258,228],{"class":87},[37,3260,203],{"class":69},[37,3262,206],{"class":69},[37,3264,209],{"class":76},[37,3266,3267],{"class":80},"(url, { signal: controller.signal });\n",[37,3269,3270,3273,3275],{"class":39,"line":267},[37,3271,3272],{"class":80},"} ",[37,3274,472],{"class":69},[37,3276,3277],{"class":80}," (err) {\n",[37,3279,3280,3282,3285,3287,3290,3292,3294,3296,3299],{"class":39,"line":273},[37,3281,2899],{"class":69},[37,3283,3284],{"class":80}," (err.name ",[37,3286,3146],{"class":69},[37,3288,3289],{"class":135}," \"AbortError\"",[37,3291,3152],{"class":80},[37,3293,415],{"class":76},[37,3295,132],{"class":80},[37,3297,3298],{"class":135},"\"cancelled\"",[37,3300,1075],{"class":80},[37,3302,3303],{"class":39,"line":284},[37,3304,259],{"class":80},[37,3306,3307],{"class":39,"line":298},[37,3308,63],{"emptyLinePlaceholder":62},[37,3310,3311],{"class":39,"line":323},[37,3312,3313],{"class":43},"\u002F\u002F ── `await` in any expression (not just statements) ──\n",[37,3315,3316,3318,3320,3322,3324,3326,3329,3332,3335,3337,3340,3342,3345,3347,3349,3351,3353],{"class":39,"line":340},[37,3317,521],{"class":69},[37,3319,524],{"class":87},[37,3321,203],{"class":69},[37,3323,1218],{"class":80},[37,3325,1738],{"class":69},[37,3327,3328],{"class":76}," getData",[37,3330,3331],{"class":80},"()).",[37,3333,3334],{"class":76},"filter",[37,3336,132],{"class":80},[37,3338,3339],{"class":309},"x",[37,3341,313],{"class":69},[37,3343,3344],{"class":80}," x.active).",[37,3346,1889],{"class":76},[37,3348,132],{"class":80},[37,3350,3339],{"class":309},[37,3352,313],{"class":69},[37,3354,3355],{"class":80}," x.name);\n",[37,3357,3358],{"class":39,"line":345},[37,3359,3360],{"class":43},"\u002F\u002F ⚠️ await has lower precedence than .filter\u002F.map — it waits for getData() first,\n",[37,3362,3363],{"class":39,"line":350},[37,3364,3365],{"class":43},"\u002F\u002F then the chain runs on the result. Wrap in parens if needed: await (getData().then(...)).\n",[37,3367,3368],{"class":39,"line":356},[37,3369,63],{"emptyLinePlaceholder":62},[37,3371,3372],{"class":39,"line":368},[37,3373,3374],{"class":43},"\u002F\u002F ── `async` arrow functions ──\n",[37,3376,3377,3379,3382,3384,3387,3389,3391,3393,3395,3397,3399,3401,3403,3405,3408,3410,3412],{"class":39,"line":377},[37,3378,521],{"class":69},[37,3380,3381],{"class":76}," asyncArrow",[37,3383,203],{"class":69},[37,3385,3386],{"class":69}," async",[37,3388,1218],{"class":80},[37,3390,3339],{"class":309},[37,3392,2592],{"class":80},[37,3394,2331],{"class":69},[37,3396,2768],{"class":80},[37,3398,84],{"class":69},[37,3400,206],{"class":69},[37,3402,209],{"class":76},[37,3404,132],{"class":80},[37,3406,3407],{"class":135},"`\u002F${",[37,3409,3339],{"class":80},[37,3411,909],{"class":135},[37,3413,3414],{"class":80},"); };\n",[37,3416,3417,3419,3422,3424,3426,3428,3430,3432,3434,3436,3438,3440,3442,3444,3446],{"class":39,"line":409},[37,3418,521],{"class":69},[37,3420,3421],{"class":76}," asyncArrow2",[37,3423,203],{"class":69},[37,3425,3386],{"class":69},[37,3427,1218],{"class":80},[37,3429,3339],{"class":309},[37,3431,2592],{"class":80},[37,3433,2331],{"class":69},[37,3435,209],{"class":76},[37,3437,132],{"class":80},[37,3439,3407],{"class":135},[37,3441,3339],{"class":80},[37,3443,909],{"class":135},[37,3445,217],{"class":80},[37,3447,3448],{"class":43},"\u002F\u002F fetch returns a Promise → await is optional\n",[15,3450,3452],{"id":3451},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[25,3454,3455],{"language":27},[29,3456,3458],{"className":31,"code":3457,"language":27,"meta":33,"style":33},"\u002F\u002F ── `await` in a regular `for` loop is sequential (not concurrent) ──\nfor (const url of urls) {\n    await fetch(url);  \u002F\u002F waits for each URL one at a time (slow)\n}\n\u002F\u002F Use Promise.all for concurrency: await Promise.all(urls.map(fetch));\n\n\u002F\u002F ── `await` in `.map` doesn't work without `async` ──\nurls.map(url => await fetch(url));  \u002F\u002F ✗ SyntaxError: await in non-async function\nurls.map(async url => await fetch(url));  \u002F\u002F ✓ async callback — but returns an array of Promises!\n\u002F\u002F Must await Promise.all: await Promise.all(urls.map(async url => await fetch(url)));\n\n\u002F\u002F ── `forEach` doesn't await (it's not async-aware) ──\nitems.forEach(async item => {\n    await process(item);  \u002F\u002F forEach doesn't wait — all items start at once (fire and forget)\n});\nconsole.log(\"done\");  \u002F\u002F logs before any process() completes (forEach doesn't await)\n\u002F\u002F Fix: use for...of (sequential) or Promise.all (concurrent)\n\n\u002F\u002F ── Unhandled rejection in async function ──\nasync function f() { throw new Error(\"oops\"); }\nf();  \u002F\u002F UnhandledPromiseRejection (no .catch, no try\u002Fcatch in caller)\n\u002F\u002F Fix: f().catch(console.error) or try { await f() } catch { ... }\n\n\u002F\u002F ── Top-level await is ESM-only ──\n\u002F\u002F In CommonJS or non-module scripts, top-level await is a SyntaxError.\n\u002F\u002F Use async IIFE: (async () => { await ... })();\n\n\u002F\u002F ── `return await` vs `return Promise` (minor performance difference) ──\nasync function f1() { return Promise.resolve(42); }  \u002F\u002F returns the Promise directly (no await overhead)\nasync function f2() { return await Promise.resolve(42); }  \u002F\u002F awaits first, then wraps in Promise.resolve\n\u002F\u002F `return await` adds an extra microtask tick (negligible, but matters for stack traces and finally blocks)\n\u002F\u002F `return await` ensures finally blocks run before the Promise resolves (important for cleanup).\n",[20,3459,3460,3465,3479,3491,3495,3500,3504,3509,3532,3555,3560,3564,3569,3586,3598,3602,3618,3623,3627,3632,3656,3666,3671,3675,3680,3685,3690,3694,3699,3728,3758,3763],{"__ignoreMap":33},[37,3461,3462],{"class":39,"line":40},[37,3463,3464],{"class":43},"\u002F\u002F ── `await` in a regular `for` loop is sequential (not concurrent) ──\n",[37,3466,3467,3469,3471,3473,3475,3477],{"class":39,"line":47},[37,3468,2643],{"class":69},[37,3470,1218],{"class":80},[37,3472,521],{"class":69},[37,3474,1791],{"class":87},[37,3476,1794],{"class":69},[37,3478,1797],{"class":80},[37,3480,3481,3483,3485,3488],{"class":39,"line":53},[37,3482,1030],{"class":69},[37,3484,209],{"class":76},[37,3486,3487],{"class":80},"(url);  ",[37,3489,3490],{"class":43},"\u002F\u002F waits for each URL one at a time (slow)\n",[37,3492,3493],{"class":39,"line":59},[37,3494,259],{"class":80},[37,3496,3497],{"class":39,"line":66},[37,3498,3499],{"class":43},"\u002F\u002F Use Promise.all for concurrency: await Promise.all(urls.map(fetch));\n",[37,3501,3502],{"class":39,"line":94},[37,3503,63],{"emptyLinePlaceholder":62},[37,3505,3506],{"class":39,"line":106},[37,3507,3508],{"class":43},"\u002F\u002F ── `await` in `.map` doesn't work without `async` ──\n",[37,3510,3511,3514,3516,3518,3520,3522,3524,3526,3529],{"class":39,"line":111},[37,3512,3513],{"class":80},"urls.",[37,3515,1889],{"class":76},[37,3517,132],{"class":80},[37,3519,1894],{"class":309},[37,3521,313],{"class":69},[37,3523,206],{"class":69},[37,3525,209],{"class":76},[37,3527,3528],{"class":80},"(url));  ",[37,3530,3531],{"class":43},"\u002F\u002F ✗ SyntaxError: await in non-async function\n",[37,3533,3534,3536,3538,3540,3542,3544,3546,3548,3550,3552],{"class":39,"line":142},[37,3535,3513],{"class":80},[37,3537,1889],{"class":76},[37,3539,132],{"class":80},[37,3541,70],{"class":69},[37,3543,1791],{"class":309},[37,3545,313],{"class":69},[37,3547,206],{"class":69},[37,3549,209],{"class":76},[37,3551,3528],{"class":80},[37,3553,3554],{"class":43},"\u002F\u002F ✓ async callback — but returns an array of Promises!\n",[37,3556,3557],{"class":39,"line":153},[37,3558,3559],{"class":43},"\u002F\u002F Must await Promise.all: await Promise.all(urls.map(async url => await fetch(url)));\n",[37,3561,3562],{"class":39,"line":158},[37,3563,63],{"emptyLinePlaceholder":62},[37,3565,3566],{"class":39,"line":164},[37,3567,3568],{"class":43},"\u002F\u002F ── `forEach` doesn't await (it's not async-aware) ──\n",[37,3570,3571,3574,3576,3578,3580,3582,3584],{"class":39,"line":170},[37,3572,3573],{"class":80},"items.",[37,3575,3120],{"class":76},[37,3577,132],{"class":80},[37,3579,70],{"class":69},[37,3581,1983],{"class":309},[37,3583,313],{"class":69},[37,3585,374],{"class":80},[37,3587,3588,3590,3593,3595],{"class":39,"line":175},[37,3589,1030],{"class":69},[37,3591,3592],{"class":76}," process",[37,3594,2672],{"class":80},[37,3596,3597],{"class":43},"\u002F\u002F forEach doesn't wait — all items start at once (fire and forget)\n",[37,3599,3600],{"class":39,"line":181},[37,3601,3193],{"class":80},[37,3603,3604,3606,3608,3610,3613,3615],{"class":39,"line":194},[37,3605,1118],{"class":80},[37,3607,415],{"class":76},[37,3609,132],{"class":80},[37,3611,3612],{"class":135},"\"done\"",[37,3614,217],{"class":80},[37,3616,3617],{"class":43},"\u002F\u002F logs before any process() completes (forEach doesn't await)\n",[37,3619,3620],{"class":39,"line":223},[37,3621,3622],{"class":43},"\u002F\u002F Fix: use for...of (sequential) or Promise.all (concurrent)\n",[37,3624,3625],{"class":39,"line":247},[37,3626,63],{"emptyLinePlaceholder":62},[37,3628,3629],{"class":39,"line":256},[37,3630,3631],{"class":43},"\u002F\u002F ── Unhandled rejection in async function ──\n",[37,3633,3634,3636,3638,3641,3643,3645,3647,3649,3651,3654],{"class":39,"line":262},[37,3635,70],{"class":69},[37,3637,73],{"class":69},[37,3639,3640],{"class":76}," f",[37,3642,81],{"class":80},[37,3644,123],{"class":69},[37,3646,126],{"class":69},[37,3648,129],{"class":76},[37,3650,132],{"class":80},[37,3652,3653],{"class":135},"\"oops\"",[37,3655,139],{"class":80},[37,3657,3658,3661,3663],{"class":39,"line":267},[37,3659,3660],{"class":76},"f",[37,3662,100],{"class":80},[37,3664,3665],{"class":43},"\u002F\u002F UnhandledPromiseRejection (no .catch, no try\u002Fcatch in caller)\n",[37,3667,3668],{"class":39,"line":273},[37,3669,3670],{"class":43},"\u002F\u002F Fix: f().catch(console.error) or try { await f() } catch { ... }\n",[37,3672,3673],{"class":39,"line":284},[37,3674,63],{"emptyLinePlaceholder":62},[37,3676,3677],{"class":39,"line":298},[37,3678,3679],{"class":43},"\u002F\u002F ── Top-level await is ESM-only ──\n",[37,3681,3682],{"class":39,"line":323},[37,3683,3684],{"class":43},"\u002F\u002F In CommonJS or non-module scripts, top-level await is a SyntaxError.\n",[37,3686,3687],{"class":39,"line":340},[37,3688,3689],{"class":43},"\u002F\u002F Use async IIFE: (async () => { await ... })();\n",[37,3691,3692],{"class":39,"line":345},[37,3693,63],{"emptyLinePlaceholder":62},[37,3695,3696],{"class":39,"line":350},[37,3697,3698],{"class":43},"\u002F\u002F ── `return await` vs `return Promise` (minor performance difference) ──\n",[37,3700,3701,3703,3705,3708,3710,3712,3714,3716,3718,3720,3722,3725],{"class":39,"line":356},[37,3702,70],{"class":69},[37,3704,73],{"class":69},[37,3706,3707],{"class":76}," f1",[37,3709,81],{"class":80},[37,3711,84],{"class":69},[37,3713,390],{"class":87},[37,3715,393],{"class":80},[37,3717,396],{"class":76},[37,3719,132],{"class":80},[37,3721,401],{"class":87},[37,3723,3724],{"class":80},"); }  ",[37,3726,3727],{"class":43},"\u002F\u002F returns the Promise directly (no await overhead)\n",[37,3729,3730,3732,3734,3737,3739,3741,3743,3745,3747,3749,3751,3753,3755],{"class":39,"line":368},[37,3731,70],{"class":69},[37,3733,73],{"class":69},[37,3735,3736],{"class":76}," f2",[37,3738,81],{"class":80},[37,3740,84],{"class":69},[37,3742,206],{"class":69},[37,3744,390],{"class":87},[37,3746,393],{"class":80},[37,3748,396],{"class":76},[37,3750,132],{"class":80},[37,3752,401],{"class":87},[37,3754,3724],{"class":80},[37,3756,3757],{"class":43},"\u002F\u002F awaits first, then wraps in Promise.resolve\n",[37,3759,3760],{"class":39,"line":377},[37,3761,3762],{"class":43},"\u002F\u002F `return await` adds an extra microtask tick (negligible, but matters for stack traces and finally blocks)\n",[37,3764,3765],{"class":39,"line":409},[37,3766,3767],{"class":43},"\u002F\u002F `return await` ensures finally blocks run before the Promise resolves (important for cleanup).\n",[15,3769,3771],{"id":3770},"quick-quiz","🧠 Quick Quiz",[3773,3774,3775],"p",{},"What's the output order?",[25,3777,3778],{"language":27},[29,3779,3781],{"className":31,"code":3780,"language":27,"meta":33,"style":33},"async function test() {\n    console.log(\"A\");\n    await Promise.resolve();\n    console.log(\"C\");\n}\nconsole.log(\"B\");\ntest();\nconsole.log(\"D\");\n",[20,3782,3783,3794,3806,3818,3830,3834,3846,3853],{"__ignoreMap":33},[37,3784,3785,3787,3789,3792],{"class":39,"line":40},[37,3786,70],{"class":69},[37,3788,73],{"class":69},[37,3790,3791],{"class":76}," test",[37,3793,191],{"class":80},[37,3795,3796,3798,3800,3802,3804],{"class":39,"line":47},[37,3797,1065],{"class":80},[37,3799,415],{"class":76},[37,3801,132],{"class":80},[37,3803,1072],{"class":135},[37,3805,1075],{"class":80},[37,3807,3808,3810,3812,3814,3816],{"class":39,"line":53},[37,3809,1030],{"class":69},[37,3811,390],{"class":87},[37,3813,393],{"class":80},[37,3815,396],{"class":76},[37,3817,1136],{"class":80},[37,3819,3820,3822,3824,3826,3828],{"class":39,"line":59},[37,3821,1065],{"class":80},[37,3823,415],{"class":76},[37,3825,132],{"class":80},[37,3827,1102],{"class":135},[37,3829,1075],{"class":80},[37,3831,3832],{"class":39,"line":66},[37,3833,259],{"class":80},[37,3835,3836,3838,3840,3842,3844],{"class":39,"line":94},[37,3837,1118],{"class":80},[37,3839,415],{"class":76},[37,3841,132],{"class":80},[37,3843,1125],{"class":135},[37,3845,1075],{"class":80},[37,3847,3848,3851],{"class":39,"line":106},[37,3849,3850],{"class":76},"test",[37,3852,1136],{"class":80},[37,3854,3855,3857,3859,3861,3863],{"class":39,"line":111},[37,3856,1118],{"class":80},[37,3858,415],{"class":76},[37,3860,132],{"class":80},[37,3862,1148],{"class":135},[37,3864,1075],{"class":80},[3866,3867,3868,3872,3880,3947],"details",{},[3869,3870,3871],"summary",{},"Answer",[29,3873,3878],{"className":3874,"code":3876,"language":3877},[3875],"language-text","B\nA\nD\nC\n","text",[20,3879,3876],{"__ignoreMap":33},[3881,3882,3883,3898,3912,3924,3936],"ol",{},[3884,3885,3886,3889,3890,3893,3894,3897],"li",{},[20,3887,3888],{},"B"," — ",[20,3891,3892],{},"console.log(\"B\")"," runs first (synchronous, before ",[20,3895,3896],{},"test()"," is called)",[3884,3899,3900,3889,3903,3905,3906,3909,3910],{},[20,3901,3902],{},"A",[20,3904,3896],{}," is called: ",[20,3907,3908],{},"console.log(\"A\")"," runs synchronously inside ",[20,3911,3850],{},[3884,3913,3914,3916,3917,3889,3919,3923],{},[20,3915,3850],{}," hits ",[20,3918,1738],{},[3920,3921,3922],"strong",{},"suspends"," (returns control to the caller)",[3884,3925,3926,3889,3929,3932,3933,3935],{},[20,3927,3928],{},"D",[20,3930,3931],{},"console.log(\"D\")"," runs (back in the main thread, ",[20,3934,3850],{}," is suspended)",[3884,3937,3938,3889,3941,3943,3944],{},[20,3939,3940],{},"C",[20,3942,3850],{}," resumes as a microtask (after the current synchronous code finishes): ",[20,3945,3946],{},"console.log(\"C\")",[3773,3948,3949,3952,3953,3955,3956,3958,3959,3962,3963,3965,3966,3968,3969,3971],{},[3920,3950,3951],{},"The lesson",": ",[20,3954,1738],{}," suspends the async function and yields control back to the caller. The code after ",[20,3957,1738],{}," runs as a ",[3920,3960,3961],{},"microtask"," (after the current synchronous code completes). This is why ",[20,3964,3928],{}," prints before ",[20,3967,3940],{}," even though ",[20,3970,3940],{}," appears earlier in the source.",[3973,3974,3975],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}",{"title":33,"searchDepth":47,"depth":47,"links":3977},[3978,3980,3981,3983,3985,3986,3987,3988,3989],{"id":17,"depth":47,"text":3979},"How async\u002Fawait Desugars to Promises",{"id":565,"depth":47,"text":566},{"id":1159,"depth":47,"text":3982},"Error Handling with try\u002Fcatch",{"id":1734,"depth":47,"text":3984},"Anti-Pattern: await in a Loop (Sequential When You Want Concurrent)",{"id":2239,"depth":47,"text":2240},{"id":2474,"depth":47,"text":2475},{"id":2982,"depth":47,"text":2983},{"id":3451,"depth":47,"text":3452},{"id":3770,"depth":47,"text":3771},"Deep-dive into async\u002Fawait: how await desugars to Promise.then, the suspension\u002Fresumption model, sequential vs concurrent execution, error handling patterns, and top-level await. Code-first reference for senior engineers.","md",{},"\u002Fjs\u002F17-async-await",{"title":5,"description":3990},"js\u002F17-async-await","WTQsgDEfXXEaSzxdn9Y7ULtU7Qz5ixXOhLv5gLwmtys",1789924649380]