[{"data":1,"prerenderedAt":636},["ShallowReactive",2],{"article-mastering-the-art-of-asynchronous-javascript-in-2024-a-deep-dive-into-promises-async-await-and-modern-patterns":3,"authors":620},{"id":4,"title":5,"author":6,"body":7,"date":611,"description":612,"extension":613,"meta":614,"navigation":119,"path":615,"seo":616,"stem":617,"thumbnail":618,"__hash__":619},"article\u002Farticle\u002Fmastering-the-art-of-asynchronous-javascript-in-2024-a-deep-dive-into-promises-async-await-and-modern-patterns.md","Mastering the Art of Asynchronous JavaScript","ashwin",{"type":8,"value":9,"toc":603},"minimark",[10,18,22,34,40,47,50,55,139,154,160,173,181,234,247,253,256,262,268,306,312,366,372,378,381,387,390,396,407,413,420,487,493,496,583,586,592,599],[11,12,14],"h3",{"id":13},"introduction-to-asynchronous-javascript",[15,16,17],"strong",{},"Introduction to Asynchronous JavaScript",[19,20,21],"p",{},"Asynchronous JavaScript is key to building responsive, efficient applications by allowing code to perform tasks without blocking the main thread. This means that instead of waiting for one task to finish before starting another, JavaScript can handle multiple tasks concurrently—like fetching data from a server while the user continues interacting with the app.",[19,23,24,25,29,30,33],{},"Historically, async tasks were managed using callbacks. However, this could lead to \"callback hell,\" where nested functions became difficult to read and maintain. With the introduction of Promises, and later ",[26,27,28],"code",{},"async","\u002F",[26,31,32],{},"await",", handling asynchronous code has become far more streamlined.",[11,35,37],{"id":36},"promises-and-asyncawait-in-2024",[15,38,39],{},"Promises and Async\u002FAwait in 2024",[41,42,44],"h4",{"id":43},"_1-promises",[15,45,46],{},"1. Promises",[19,48,49],{},"A Promise in JavaScript represents a value that may not be available yet but will be resolved at some future time. Promises can either be fulfilled, rejected, or pending. This allows us to structure asynchronous operations in a more readable, chainable way.",[19,51,52],{},[15,53,54],{},"Example: Fetching Data with a Promise",[56,57,62],"pre",{"className":58,"code":59,"language":60,"meta":61,"style":61},"language-javascript shiki shiki-themes material-theme-darker","function fetchData() {\n  return new Promise((resolve, reject) => {\n    setTimeout(() => {\n      const data = { message: \"Data fetched successfully\" };\n      resolve(data);\n    }, 2000); \u002F\u002F Simulating a network delay\n  });\n}\n\nfetchData()\n  .then(response => console.log(response.message))\n  .catch(error => console.error(\"Error:\", error));\n","javascript","",[26,63,64,72,78,84,90,96,102,108,114,121,127,133],{"__ignoreMap":61},[65,66,69],"span",{"class":67,"line":68},"line",1,[65,70,71],{},"function fetchData() {\n",[65,73,75],{"class":67,"line":74},2,[65,76,77],{},"  return new Promise((resolve, reject) => {\n",[65,79,81],{"class":67,"line":80},3,[65,82,83],{},"    setTimeout(() => {\n",[65,85,87],{"class":67,"line":86},4,[65,88,89],{},"      const data = { message: \"Data fetched successfully\" };\n",[65,91,93],{"class":67,"line":92},5,[65,94,95],{},"      resolve(data);\n",[65,97,99],{"class":67,"line":98},6,[65,100,101],{},"    }, 2000); \u002F\u002F Simulating a network delay\n",[65,103,105],{"class":67,"line":104},7,[65,106,107],{},"  });\n",[65,109,111],{"class":67,"line":110},8,[65,112,113],{},"}\n",[65,115,117],{"class":67,"line":116},9,[65,118,120],{"emptyLinePlaceholder":119},true,"\n",[65,122,124],{"class":67,"line":123},10,[65,125,126],{},"fetchData()\n",[65,128,130],{"class":67,"line":129},11,[65,131,132],{},"  .then(response => console.log(response.message))\n",[65,134,136],{"class":67,"line":135},12,[65,137,138],{},"  .catch(error => console.error(\"Error:\", error));\n",[19,140,141,142,145,146,149,150,153],{},"In this example, ",[26,143,144],{},"fetchData"," returns a Promise that resolves with a success message after 2 seconds. The ",[26,147,148],{},"then"," method handles the resolved data, while ",[26,151,152],{},"catch"," handles any errors.",[41,155,157],{"id":156},"_2-asyncawait",[15,158,159],{},"2. Async\u002FAwait",[19,161,162,29,164,166,167,169,170,172],{},[26,163,28],{},[26,165,32],{}," builds on Promises, allowing us to write asynchronous code that reads like synchronous code. An ",[26,168,28],{}," function returns a Promise, and ",[26,171,32],{}," pauses the function until the Promise resolves.",[19,174,175],{},[15,176,177,178,180],{},"Example: Rewriting ",[26,179,144],{}," with Async\u002FAwait",[56,182,184],{"className":58,"code":183,"language":60,"meta":61,"style":61},"async function fetchDataAsync() {\n  try {\n    const data = await fetchData();\n    console.log(data.message);\n  } catch (error) {\n    console.error(\"Error:\", error);\n  }\n}\n\nfetchDataAsync();\n",[26,185,186,191,196,201,206,211,216,221,225,229],{"__ignoreMap":61},[65,187,188],{"class":67,"line":68},[65,189,190],{},"async function fetchDataAsync() {\n",[65,192,193],{"class":67,"line":74},[65,194,195],{},"  try {\n",[65,197,198],{"class":67,"line":80},[65,199,200],{},"    const data = await fetchData();\n",[65,202,203],{"class":67,"line":86},[65,204,205],{},"    console.log(data.message);\n",[65,207,208],{"class":67,"line":92},[65,209,210],{},"  } catch (error) {\n",[65,212,213],{"class":67,"line":98},[65,214,215],{},"    console.error(\"Error:\", error);\n",[65,217,218],{"class":67,"line":104},[65,219,220],{},"  }\n",[65,222,223],{"class":67,"line":110},[65,224,113],{},[65,226,227],{"class":67,"line":116},[65,228,120],{"emptyLinePlaceholder":119},[65,230,231],{"class":67,"line":123},[65,232,233],{},"fetchDataAsync();\n",[19,235,236,237,239,240,242,243,246],{},"Here, ",[26,238,32],{}," pauses execution until ",[26,241,144],{}," resolves. This makes error handling easier, as ",[26,244,245],{},"try\u002Fcatch"," can be used directly around the asynchronous logic.",[11,248,250],{"id":249},"modern-async-patterns-and-tips",[15,251,252],{},"Modern Async Patterns and Tips",[19,254,255],{},"In 2024, handling multiple asynchronous operations and ensuring smooth user experiences is vital. Let’s look at some common patterns and tips for modern JavaScript async:",[41,257,259],{"id":258},"_3-promiseall-promiseallsettled-promiseany-and-promiserace",[15,260,261],{},"3. Promise.all, Promise.allSettled, Promise.any, and Promise.race",[19,263,264,267],{},[15,265,266],{},"Promise.all",": Waits for all promises in an array to resolve or any to reject.",[56,269,271],{"className":58,"code":270,"language":60,"meta":61,"style":61},"const promise1 = Promise.resolve(1);\nconst promise2 = new Promise((resolve) => setTimeout(resolve, 2000, 2));\nconst promise3 = Promise.resolve(3);\n\nPromise.all([promise1, promise2, promise3])\n  .then(values => console.log(values)) \u002F\u002F Logs: [1, 2, 3]\n  .catch(error => console.error(\"Error:\", error));\n",[26,272,273,278,283,288,292,297,302],{"__ignoreMap":61},[65,274,275],{"class":67,"line":68},[65,276,277],{},"const promise1 = Promise.resolve(1);\n",[65,279,280],{"class":67,"line":74},[65,281,282],{},"const promise2 = new Promise((resolve) => setTimeout(resolve, 2000, 2));\n",[65,284,285],{"class":67,"line":80},[65,286,287],{},"const promise3 = Promise.resolve(3);\n",[65,289,290],{"class":67,"line":86},[65,291,120],{"emptyLinePlaceholder":119},[65,293,294],{"class":67,"line":92},[65,295,296],{},"Promise.all([promise1, promise2, promise3])\n",[65,298,299],{"class":67,"line":98},[65,300,301],{},"  .then(values => console.log(values)) \u002F\u002F Logs: [1, 2, 3]\n",[65,303,304],{"class":67,"line":104},[65,305,138],{},[19,307,308,311],{},[15,309,310],{},"Promise.allSettled",": Waits for all promises to settle (either resolved or rejected).",[56,313,315],{"className":58,"code":314,"language":60,"meta":61,"style":61},"const promises = [\n  Promise.resolve(\"Resolved\"),\n  Promise.reject(\"Rejected\"),\n  Promise.resolve(\"Another Resolved\")\n];\n\nPromise.allSettled(promises).then(results => {\n  results.forEach(result => console.log(result.status, result.value || result.reason));\n});\n\u002F\u002F Logs: \"fulfilled Resolved\", \"rejected Rejected\", \"fulfilled Another Resolved\"\n",[26,316,317,322,327,332,337,342,346,351,356,361],{"__ignoreMap":61},[65,318,319],{"class":67,"line":68},[65,320,321],{},"const promises = [\n",[65,323,324],{"class":67,"line":74},[65,325,326],{},"  Promise.resolve(\"Resolved\"),\n",[65,328,329],{"class":67,"line":80},[65,330,331],{},"  Promise.reject(\"Rejected\"),\n",[65,333,334],{"class":67,"line":86},[65,335,336],{},"  Promise.resolve(\"Another Resolved\")\n",[65,338,339],{"class":67,"line":92},[65,340,341],{},"];\n",[65,343,344],{"class":67,"line":98},[65,345,120],{"emptyLinePlaceholder":119},[65,347,348],{"class":67,"line":104},[65,349,350],{},"Promise.allSettled(promises).then(results => {\n",[65,352,353],{"class":67,"line":110},[65,354,355],{},"  results.forEach(result => console.log(result.status, result.value || result.reason));\n",[65,357,358],{"class":67,"line":116},[65,359,360],{},"});\n",[65,362,363],{"class":67,"line":123},[65,364,365],{},"\u002F\u002F Logs: \"fulfilled Resolved\", \"rejected Rejected\", \"fulfilled Another Resolved\"\n",[19,367,368,371],{},[15,369,370],{},"Promise.any",": Resolves as soon as any one promise in an array resolves, ignoring rejections unless all promises reject.",[19,373,374,377],{},[15,375,376],{},"Promise.race",": Resolves or rejects as soon as the first promise settles.",[19,379,380],{},"These tools give flexibility in handling multiple asynchronous tasks based on different conditions.",[11,382,384],{"id":383},"_4-advanced-async-techniques-in-2024",[15,385,386],{},"4. Advanced Async Techniques in 2024",[19,388,389],{},"As JavaScript continues evolving, newer tools and libraries help developers manage asynchronous operations efficiently:",[41,391,393],{"id":392},"error-handling-in-large-codebases",[15,394,395],{},"Error Handling in Large Codebases",[19,397,398,399,406],{},"When building large applications, managing async code can be challenging, especially with error handling. Libraries like ",[400,401,405],"a",{"href":402,"rel":403},"https:\u002F\u002Frxjs.dev\u002F",[404],"nofollow","RxJS"," provide advanced tools for reactive programming and error handling in complex async flows.",[41,408,410],{"id":409},"concurrency-control-with-async-functions",[15,411,412],{},"Concurrency Control with Async Functions",[19,414,415,416,419],{},"Concurrency can be essential when dealing with limited resources like API rate limits. The ",[26,417,418],{},"p-limit"," package can help control how many promises run at once.",[56,421,423],{"className":58,"code":422,"language":60,"meta":61,"style":61},"const pLimit = require(\"p-limit\");\nconst limit = pLimit(2); \u002F\u002F Limit to 2 concurrent tasks\n\nconst tasks = [\n  () => fetchData(),\n  () => fetchData(),\n  () => fetchData()\n];\n\n(async () => {\n  const results = await Promise.all(tasks.map(task => limit(task)));\n  console.log(results);\n})();\n",[26,424,425,430,435,439,444,449,453,458,462,466,471,476,481],{"__ignoreMap":61},[65,426,427],{"class":67,"line":68},[65,428,429],{},"const pLimit = require(\"p-limit\");\n",[65,431,432],{"class":67,"line":74},[65,433,434],{},"const limit = pLimit(2); \u002F\u002F Limit to 2 concurrent tasks\n",[65,436,437],{"class":67,"line":80},[65,438,120],{"emptyLinePlaceholder":119},[65,440,441],{"class":67,"line":86},[65,442,443],{},"const tasks = [\n",[65,445,446],{"class":67,"line":92},[65,447,448],{},"  () => fetchData(),\n",[65,450,451],{"class":67,"line":98},[65,452,448],{},[65,454,455],{"class":67,"line":104},[65,456,457],{},"  () => fetchData()\n",[65,459,460],{"class":67,"line":110},[65,461,341],{},[65,463,464],{"class":67,"line":116},[65,465,120],{"emptyLinePlaceholder":119},[65,467,468],{"class":67,"line":123},[65,469,470],{},"(async () => {\n",[65,472,473],{"class":67,"line":129},[65,474,475],{},"  const results = await Promise.all(tasks.map(task => limit(task)));\n",[65,477,478],{"class":67,"line":135},[65,479,480],{},"  console.log(results);\n",[65,482,484],{"class":67,"line":483},13,[65,485,486],{},"})();\n",[11,488,490],{"id":489},"real-world-examples",[15,491,492],{},"Real-World Examples",[19,494,495],{},"Let’s apply these techniques to a real-world example, like fetching user data from multiple APIs and displaying them in a dashboard.",[56,497,499],{"className":58,"code":498,"language":60,"meta":61,"style":61},"async function fetchUserData() {\n  try {\n    const userData = await Promise.all([\n      fetch(\"https:\u002F\u002Fapi.example.com\u002Fuser\u002Fprofile\"),\n      fetch(\"https:\u002F\u002Fapi.example.com\u002Fuser\u002Fstats\")\n    ]);\n\n    const [profile, stats] = await Promise.all(userData.map(res => res.json()));\n    console.log(\"User Profile:\", profile);\n    console.log(\"User Stats:\", stats);\n\n  } catch (error) {\n    console.error(\"Failed to fetch user data:\", error);\n  }\n}\n\nfetchUserData();\n",[26,500,501,506,510,515,520,525,530,534,539,544,549,553,557,562,567,572,577],{"__ignoreMap":61},[65,502,503],{"class":67,"line":68},[65,504,505],{},"async function fetchUserData() {\n",[65,507,508],{"class":67,"line":74},[65,509,195],{},[65,511,512],{"class":67,"line":80},[65,513,514],{},"    const userData = await Promise.all([\n",[65,516,517],{"class":67,"line":86},[65,518,519],{},"      fetch(\"https:\u002F\u002Fapi.example.com\u002Fuser\u002Fprofile\"),\n",[65,521,522],{"class":67,"line":92},[65,523,524],{},"      fetch(\"https:\u002F\u002Fapi.example.com\u002Fuser\u002Fstats\")\n",[65,526,527],{"class":67,"line":98},[65,528,529],{},"    ]);\n",[65,531,532],{"class":67,"line":104},[65,533,120],{"emptyLinePlaceholder":119},[65,535,536],{"class":67,"line":110},[65,537,538],{},"    const [profile, stats] = await Promise.all(userData.map(res => res.json()));\n",[65,540,541],{"class":67,"line":116},[65,542,543],{},"    console.log(\"User Profile:\", profile);\n",[65,545,546],{"class":67,"line":123},[65,547,548],{},"    console.log(\"User Stats:\", stats);\n",[65,550,551],{"class":67,"line":129},[65,552,120],{"emptyLinePlaceholder":119},[65,554,555],{"class":67,"line":135},[65,556,210],{},[65,558,559],{"class":67,"line":483},[65,560,561],{},"    console.error(\"Failed to fetch user data:\", error);\n",[65,563,565],{"class":67,"line":564},14,[65,566,220],{},[65,568,570],{"class":67,"line":569},15,[65,571,113],{},[65,573,575],{"class":67,"line":574},16,[65,576,120],{"emptyLinePlaceholder":119},[65,578,580],{"class":67,"line":579},17,[65,581,582],{},"fetchUserData();\n",[19,584,585],{},"This example fetches user profile and stats data concurrently, improving performance by reducing the overall time taken to complete both requests.",[11,587,589],{"id":588},"conclusion",[15,590,591],{},"Conclusion",[19,593,594,595,598],{},"Asynchronous JavaScript is a core skill for developers in 2024, as modern web applications increasingly rely on concurrent, non-blocking tasks to improve user experience. Mastering ",[26,596,597],{},"async\u002Fawait"," with these advanced patterns and leveraging libraries for reactive programming can make your code more efficient, maintainable, and resilient. As JavaScript continues to evolve, staying updated on async techniques will be essential for effective coding in both front and backend development.",[600,601,602],"style",{},"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);}",{"title":61,"searchDepth":74,"depth":74,"links":604},[605,606,607,608,609,610],{"id":13,"depth":80,"text":17},{"id":36,"depth":80,"text":39},{"id":249,"depth":80,"text":252},{"id":383,"depth":80,"text":386},{"id":489,"depth":80,"text":492},{"id":588,"depth":80,"text":591},"2024-11-06T08:30:07.083Z","A Deep Dive into Promises, Async\u002FAwait, and Modern Patterns","md",{},"\u002Farticle\u002Fmastering-the-art-of-asynchronous-javascript-in-2024-a-deep-dive-into-promises-async-await-and-modern-patterns",{"title":5,"description":612},"article\u002Fmastering-the-art-of-asynchronous-javascript-in-2024-a-deep-dive-into-promises-async-await-and-modern-patterns","\u002Fimg\u002Fjs-tip.png","3lUxvXH38IPFNWqh3vYqnw0DVkk4o71ye7767fzL29I",{"id":621,"extension":622,"meta":623,"stem":634,"__hash__":635},"author\u002Fauthor\u002FauthorDetails.json","json",{"body":624},[625,629],{"id":6,"fullName":626,"description":627,"image":628},"Ashwin K Shenoy","Hi! I am Ashwin, an Software Engineer and Consultant based out of Bengaluru, India.","https:\u002F\u002Fsimpletech.xyz\u002Fimg\u002Fauthor\u002Fashwin.jpg",{"id":630,"fullName":631,"description":632,"image":633},"paul","Paul Shan","Hello! I am Paul, a front end engineer and consultant based out of Bengaluru, India.","https:\u002F\u002Fashwinshenoy.com\u002Fimg\u002Fashwin2.jpg","author\u002FauthorDetails","k8atXxcwAcv_rjC8llPba18X62upiKWYGU5dL4-S4lw",1782187479716]