Why does your `async` function never resolve? 😳 Last week, I ran headlong into one of those bugs that only make sense once you understand the quirks of JavaScript's `async/await`. A colleague handed me some code, scratching their head over an `await` that seemed to hang forever. Here's a simplified version: ```javascript async function fetchData() { return await new Promise((resolve, reject) => { // Some operations resolve('Data'); }); } const result = fetchData().then(console.log); ``` The code looks fine at first glance. The promise resolves, so why is it not logging the data? The culprit? A classic misunderstanding: forgetting to `return` promises from within an `async` function. The `fetchData()` function was invoked without `await`, causing it to return a promise that remained unresolved at the outer level. A quick fix involved ensuring that we handle the promise correctly: ```javascript async function fetchData() { return new Promise((resolve, reject) => { // Some operations resolve('Data'); }); } (async () => { const result = await fetchData(); console.log(result); })(); ``` This subtle mistake can evade detection, especially since local development environments might not reflect the production state, leading to unanticipated hangs. Have you ever been bitten by an async bug that had you pulling out your hair? Share your story or thoughts in the comments. Let's help each other navigate these pitfalls together! 🧑💻 #JavaScript #NodeJS #AsyncProgramming #JavaScript #NodeJS #AsyncProgramming
Async Function Hangs: Misunderstanding Async/Await in JavaScript
More Relevant Posts
-
🧹 JavaScript is evolving to make 𝗿𝗲𝘀𝗼𝘂𝗿𝗰𝗲 𝗰𝗹𝗲𝗮𝗻𝘂𝗽 more explicit and reliable JavaScript's 𝗺𝗲𝗺𝗼𝗿𝘆 𝗺𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁 has long been implicit; garbage collection happens without developer control, and cleaning up resources like open streams, sockets, or iterators has been ad hoc at best. That's changing. A new explicit 𝗿𝗲𝘀𝗼𝘂𝗿𝗰𝗲 𝗺𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁 𝗽𝗿𝗼𝗽𝗼𝘀𝗮𝗹 in the ECMAScript standards process introduces a unified way to declare cleanup behavior. At its core, this includes: 🔹 A standard [𝗦𝘆𝗺𝗯𝗼𝗹.𝗱𝗶𝘀𝗽𝗼𝘀𝗲]() method: enabling a predictable cleanup interface across APIs. 🔹 A 𝘂𝘀𝗶𝗻𝗴 declaration: tying resource lifetime to scope so cleanup happens automatically when a variable goes out of scope. Example: 𝒄𝒍𝒂𝒔𝒔 𝑫𝒃𝑺𝒆𝒔𝒔𝒊𝒐𝒏 { 𝒄𝒐𝒏𝒏𝒆𝒄𝒕𝒊𝒐𝒏𝑺𝒕𝒓𝒊𝒏𝒈; 𝒄𝒐𝒏𝒔𝒕𝒓𝒖𝒄𝒕𝒐𝒓(𝒄𝒐𝒏𝒏𝒆𝒄𝒕𝒊𝒐𝒏𝑺𝒕𝒓𝒊𝒏𝒈) { 𝒕𝒉𝒊𝒔.𝒄𝒐𝒏𝒏𝒆𝒄𝒕𝒊𝒐𝒏𝑺𝒕𝒓𝒊𝒏𝒈 = 𝒄𝒐𝒏𝒏𝒆𝒄𝒕𝒊𝒐𝒏𝑺𝒕𝒓𝒊𝒏𝒈; 𝒄𝒐𝒏𝒔𝒐𝒍𝒆.𝒍𝒐𝒈(`𝑪𝒐𝒏𝒏𝒆𝒄𝒕: ${ 𝒄𝒐𝒏𝒏𝒆𝒄𝒕𝒊𝒐𝒏𝑺𝒕𝒓𝒊𝒏𝒈 }`); } 𝒒𝒖𝒆𝒓𝒚(𝒔𝒒𝒍) { 𝒄𝒐𝒏𝒔𝒐𝒍𝒆.𝒍𝒐𝒈(`𝑬𝒙𝒆𝒄𝒖𝒕𝒆 𝒒𝒖𝒆𝒓𝒚: ${ 𝒔𝒒𝒍 }`); } [𝑺𝒚𝒎𝒃𝒐𝒍.𝒅𝒊𝒔𝒑𝒐𝒔𝒆]() { 𝒄𝒐𝒏𝒔𝒐𝒍𝒆.𝒍𝒐𝒈(`𝑫𝒊𝒔𝒄𝒐𝒏𝒏𝒆𝒄𝒕: ${ 𝒕𝒉𝒊𝒔.𝒄𝒐𝒏𝒏𝒆𝒄𝒕𝒊𝒐𝒏𝑺𝒕𝒓𝒊𝒏𝒈 }`); } } 𝒄𝒐𝒏𝒔𝒕 𝒄𝒐𝒏𝒏 = "𝒑𝒐𝒔𝒕𝒈𝒓𝒆𝒔://𝒍𝒐𝒄𝒂𝒍𝒉𝒐𝒔𝒕:5432/𝒂𝒑𝒑𝒅𝒃"; 𝒊𝒇 (𝒄𝒐𝒏𝒏) { 𝒖𝒔𝒊𝒏𝒈 𝒔𝒆𝒔𝒔𝒊𝒐𝒏 = 𝒏𝒆𝒘 𝑫𝒃𝑺𝒆𝒔𝒔𝒊𝒐𝒏(𝒄𝒐𝒏𝒏); 𝒄𝒐𝒏𝒔𝒕 𝒓𝒐𝒘𝒔 = 𝒔𝒆𝒔𝒔𝒊𝒐𝒏.𝒒𝒖𝒆𝒓𝒚("𝑺𝑬𝑳𝑬𝑪𝑻 𝒊𝒅, 𝒏𝒂𝒎𝒆 𝑭𝑹𝑶𝑴 𝒖𝒔𝒆𝒓𝒔 𝑳𝑰𝑴𝑰𝑻 1"); } These additions give developers a way to both name and control cleanup logic, moving beyond the inconsistent patterns we've used for years. The proposal (already implemented in major browsers except 𝗦𝗮𝗳𝗮𝗿𝗶) standardizes garbage collection and cleanup semantics, making code more predictable and easier to reason about. For engineers who care about performance, robustness, and maintainability, this is a meaningful step forward for writing 𝗿𝗲𝘀𝗼𝘂𝗿𝗰𝗲-𝘀𝗮𝗳𝗲 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁. #JavaScript #WebDevelopment #ECMAScript #FrontendDev #BrowserAPI
To view or add a comment, sign in
-
𝗧𝗶𝗽𝘀 𝗙𝗼𝗿 𝗨𝘀𝗶𝗻𝗴 𝗧𝘆𝗽𝗲𝗦𝗰𝗿𝗶𝗽𝘁 You're stuck with JavaScript errors. You see "Cannot read property" errors. This happens when you're not sure what properties an object has. TypeScript can help. It's like JavaScript with extra checks. Here's what TypeScript does: - Tells you when you're accessing properties that don't exist - Autocompletes your objects because it knows what's in them - Documents your code through types - Refactors fearlessly because the compiler yells before users do To get started with TypeScript: - Learn the syntax - Read the handbook - Understand tsconfig.json Start with a small project. Use strict mode. You'll learn more from one strict project than ten tutorials. Let's look at an example. We have a function that fetches a user: ```javascript async function getUser(id: number): Promise<User> { const res = await fetch(`/api/users/${id}`); return res.json(); } ``` We can add type safety by using an interface for the User: ```javascript interface User { id: number; name: string; email?: string; } ``` But we still need to handle cases where the API returns something unexpected. We can use a type guard to validate the response at runtime: ```javascript function isUser(obj: unknown): obj is User { return ( typeof obj === "object" && obj !== null && id in obj && typeof (obj as User).id ===number && "name" in obj && typeof (obj as User).name === "string" ); } ``` Use Zod for response validation. Return a discriminated union for state. Handle network errors and validation failures separately. Remember: - Never use `any` — use `unknown` and narrow with type guards - Treat all external data as `unknown`, validate with Zod - Use discriminated unions for state - Prefer Result pattern over thrown exceptions - `strict: true` always Source: https://lnkd.in/g3KQZXbV
To view or add a comment, sign in
-
𝐘𝐨𝐮𝐫 𝐑𝐞𝐚𝐜𝐭 `𝐮𝐬𝐞𝐄𝐟𝐟𝐞𝐜𝐭` 𝐡𝐨𝐨𝐤 𝐦𝐢𝐠𝐡𝐭 𝐛𝐞 𝐬𝐞𝐜𝐫𝐞𝐭𝐥𝐲 𝐫𝐮𝐧𝐧𝐢𝐧𝐠 𝐚𝐧 𝐢𝐧𝐟𝐢𝐧𝐢𝐭𝐞 𝐥𝐨𝐨𝐩. Ever debugged a component where `useEffect` just keeps firing, even when its dependencies seem unchanged? The culprit is often subtle: non-primitive values in your dependency array. Let's say you have an `useEffect` that fetches data, and one of its dependencies is a helper function defined inside your component: ```javascript // Problematic pattern const myAction = () => { /* ... do something */ }; useEffect(() => { myAction(); // This function reference changes on every render! }, [myAction]); // 🚨 Danger! 'myAction' is recreated every render ``` Even if `myAction`'s logic doesn't change, its reference does on every render. To JavaScript, it's a "new" function, triggering your effect unnecessarily. This can lead to performance hits, flickering UIs, or even infinite data fetches if `myAction` triggers a state update. The Fix: Wrap those functions with `useCallback`. ```javascript // Optimized pattern const myAction = useCallback(() => { // ... your logic }, [/* any actual dependencies inside myAction itself */]); useEffect(() => { myAction(); }, [myAction]); // ✅ Now, myAction's reference is stable ``` `useCallback` ensures `myAction`'s reference only changes if its own dependencies change, preventing those annoying, silent re-runs. It keeps your effects predictable and your app performant. What's the trickiest `useEffect` bug you've ever squashed? Share your war stories! #React #ReactJS #FrontendDevelopment #JavaScript #WebPerformance
To view or add a comment, sign in
-
React just got a whole lot cleaner. ✨ If you’ve just started exploring React 19, the first thing you’ll notice is how much "boilerplate noise" we can finally delete. The shift from useEffect to the new use() hook is a perfect example. Here is the breakdown of what's happening in this image: ⬅️ The Left: The "Old" Way (React <18) This is the pattern we've used for years, but it has always felt a bit clunky: Manual State: We had to create useState for the data, the loading spinner, and the error handling. The Lifecycle Trap: We relied on useEffect to trigger the fetch on mount. Verbosity: It takes about 15 lines of code just to display one piece of data. ➡️ The Right: The "New" Way (React 19) With the introduction of the use() hook, the code becomes declarative: Direct Unwrapping: No more effects. The use(promise) hook handles the resolution of the data directly in the render path. Suspense Integration: We no longer need manual if (loading) checks. React handles the "waiting" state using <Suspense> boundaries higher up the tree. Pure Logic: We've gone from 15+ lines of ceremony to just 2 or 3 lines of actual logic. I am officially moving our projects toward this cleaner, more readable syntax. hashtag #webdeveloper hashtag #ReactJS hashtag #React19 hashtag #react18 hashtag #WebDevelopment hashtag #CleanCode hashtag #JavaScript hashtag #SoftwareEngineering hashtag #Frontend hashtag #Reactnative
To view or add a comment, sign in
-
-
I recently tackled refactoring an older API integration in a JavaScript project. The existing codebase was a maze of nested callbacks and `.then()` chains, which had become incredibly challenging to read and debug, especially when dealing with error states. My primary goal was to modernize it using `async/await` to enhance readability and simplify the asynchronous flow. While the initial conversion made the code look much cleaner, almost synchronous, I quickly realized I wasn't handling errors as robustly as I thought. A single broad `try...catch` around the entire `async` function didn't provide the granularity needed for specific network or data processing failures within the `await` sequence. The real breakthrough came when I started placing `try...catch` blocks more strategically around individual `await` calls that were potential points of failure, rather than just the encompassing `async` function. This approach allowed me to catch and handle errors from specific promises precisely, providing more accurate error messages and enabling targeted fallback logic. I also revisited `Promise.allSettled` for scenarios where multiple parallel operations needed to complete regardless of individual success, collecting all outcomes efficiently. What I learned: While `async/await` dramatically improves code clarity, it’s crucial not to abstract away the necessity for meticulous error handling. Strategically using `try...catch` for individual `await` expressions, understanding how to differentiate between synchronous exceptions and promise rejections, and leveraging tools like `Promise.allSettled` are key to building truly resilient asynchronous applications in JavaScript. Have you had a similar 'aha!' moment with `async/await` or another JavaScript feature? Share your insights and best practices in the comments below! #JavaScript #AsyncAwait #WebDevelopment #CodingTips #ErrorHandling #SoftwareEngineering #FrontendDevelopment References: 1. MDN Web Docs: async function - [https://lnkd.in/ge7pgH2f) 2. MDN Web Docs: Promise.allSettled() - [https://lnkd.in/gyS2uzj8)
To view or add a comment, sign in
-
1️⃣ Call Stack ⭐Executes synchronous JS code ⭐LIFO (Last In, First Out) ⭐Only one thing runs at a time 2️⃣ Web APIs (Browser / Node.js) ⭐Handles async operations: ⭐setTimeout ⭐fetch ⭐DOM events ⭐Runs outside the call stack 3️⃣ Task Queues There are two important queues 👇 🟡 Microtask Queue (HIGH priority) ⭐Promise.then ⭐async/await ⭐queueMicrotask 4️⃣ Event Loop (The Manager 🧑💼) Its job: ⭐Check if Call Stack is empty ⭐Execute ALL microtasks ⭐Take ONE macrotask ⭐Repeat 🔁 forever 🔍 One-Line Visualization (Easy to remember) CALL STACK ↓ WEB APIs ↓ MICROTASK QUEUE (Promises) ⭐ ↓ MACROTASK QUEUE (Timers) ↓ EVENT LOOP 🔁 #JavaScript #EventLoop #AsyncJavaScript #WebDevelopment #FrontendDeveloper #Coding #LearnToCode #DeveloperCommunity
To view or add a comment, sign in
-
-
𝟮𝟬 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗜𝗻𝘁𝗲𝗿𝘃𝗶𝗲𝘄 𝗤𝘂𝗲𝘀𝘁𝗶𝗼𝗻𝘀 𝗳𝗼𝗿 𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿𝘀 𝗶𝗻 𝟮𝟬𝟮𝟱 1. Explain the difference between Promise.all(), Promise.allSettled(), and Promise.any(). 2. How does the Nullish Coalescing Operator (??) differ from OR (||)? 3. What are WeakMap and WeakSet, and when would you use them? 4. Explain the concept of Top-Level Await. 5. How do you implement proper error boundaries in JavaScript applications? 6. What happens when you mix async/await with .then()/.catch()? 7. Explain the event loop with microtasks and macrotasks. 8. How would you implement a retry mechanism for failed API calls? 9. What is the difference between debouncing and throttling? Implement both. 10. How does JavaScript garbage collection work, and how can you optimize for it? 11. Explain tree shaking and how it affects your code. 12. What are Web Workers and when would you use them? 13. How do you handle state management without external libraries? 14. Explain the Module Federation pattern. 15. What are JavaScript Proxies and how can they be used? 16. How would you implement a custom hook pattern in vanilla JavaScript? 17. How do you prevent XSS attacks in JavaScript applications? 18. What is Content Security Policy and how does it affect JavaScript? 19. How would you test asynchronous code without external testing frameworks? 20. Explain different types of JavaScript testing (unit, integration, e2e) and their trade-offs. 𝗜 𝗵𝗮𝘃𝗲 𝗽𝗿𝗲𝗽𝗮𝗿𝗲𝗱 𝗜𝗻𝘁𝗲𝗿𝘃𝗶𝗲𝘄 𝗣𝗿𝗲𝗽𝗮𝗿𝗮𝘁𝗶𝗼𝗻 𝗚𝘂𝗶𝗱𝗲 𝗳𝗼𝗿 𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 𝗘𝗻𝗴𝗶𝗻𝗻𝗲𝗿𝘀. covering JavaScript, React, Next.js, System Design, and more. 𝗚𝗲𝘁 𝘁𝗵𝗲 𝗚𝘂𝗶𝗱𝗲 𝗵𝗲𝗿𝗲 - https://lnkd.in/d2w4VmVT 💙- If you've read so far, do LIKE and RESHARE the post
To view or add a comment, sign in
-
Day 62 of me reading random and basic but important dev topicsss..... Today I read about the Resource Loading in JavaScript...... In our day-to-day work building interfaces with React or other modern frameworks, it's easy to take module bundlers for granted. But what happens when we need to dynamically inject a third-party script......like an analytics tracker, a payment SDK, or a support widget.....on the fly? Understanding the vanilla DOM events onload and onerror is a must for any robust front-end architecture. 1. The Dynamic Injection Adding a script dynamically is straightforward: let script = document.createElement('script'); script.src = "third-party.js"; document.head.append(script); But we can't just invoke its functions immediately. The browser needs time to fetch and execute it. 2. script.onload (The Success Path) This event triggers after the script has successfully loaded and executed. This is our green light to safely use the newly available variables or functions. 3. script.onerror (The Failure Path) If the script 404s or the server is down, onerror catches it. However, keep in mind: we won't get HTTP status codes (like 404 or 500) here, just a notification that the network request failed. Loading vs. Execution Here is where we get tripped up: onload and onerror only track the network loading phase. If a script downloads successfully but contains a syntax or runtime error during execution, onload will still fire! To catch those internal execution bugs, we need a different tool entirely: the window.onerror global handler. Keep Learning!!!!! #JavaScript #WebDevelopment #FrontendDev #React #SoftwareEngineering
To view or add a comment, sign in
-
-
📌 Understanding JSON.stringify() in JavaScript When working with JavaScript applications, especially while sending data to servers or storing it locally, data often needs to be converted into JSON format. This is where JSON.stringify() plays a key role. JSON.stringify() converts a JavaScript object or value into a JSON string. 👉 It helps you send or store JavaScript data in JSON format. 💠 Why is JSON.stringify() important? 🌐 Sending data in API requests 💾 Storing objects in localStorage / sessionStorage 🔄 Data exchange between frontend and backend 🚀 Essential for real-world web applications 👉 Common Use Case (localStorage) 🔹 localStorage.setItem("user", JSON.stringify(user)); 👉 To read it back: 🔹 const savedUser = JSON.parse(localStorage.getItem("user")); 📝 Important Notes 🔹 Functions and undefined values are ignored 🔹 Circular references will cause an error 🔹 Dates are converted to strings JSON.stringify() is a fundamental JavaScript method that enables smooth data communication and storage. #JavaScript #WebDevelopment #Frontend #JSON #CodingTips #LearnJavaScript
To view or add a comment, sign in
-
-
📌 Understanding JSON.parse() in JavaScript In JavaScript, data often travels between systems in JSON (JavaScript Object Notation) format — especially when working with APIs. To use that data inside your application, JavaScript provides the JSON.parse() method. 👉 What does JSON.parse() do? 🔹 JSON.parse() converts a JSON string into a JavaScript object. 👉 In simple terms: 🔹 It helps JavaScript understand and work with JSON data. 👉 Example Explanation: 🔹 The API response is a string 🔹 JSON.parse() converts it into an object 🔹 Now we can access properties using dot notation 👉 Why is JSON.parse() important? 🌐 Used when handling API responses 💾 Converts data from localStorage / sessionStorage 🔄 Helps transform string data into usable objects 🚀 Essential for backend–frontend communication 💠 Common Error to Watch Out For 🔹 JSON.parse() only works on valid JSON. 🔹 Invalid JSON will throw an error. 🔹 JSON.parse("{name: 'Hari'}"); // ❌ Error ✔ Correct JSON format: JSON.parse('{"name":"Hari"}'); // ✅ JSON.parse() is a fundamental JavaScript method that plays a key role in real-world applications, especially while working with APIs and stored data. #JavaScript #WebDevelopment #Frontend #JSON #CodingTips #LearnJavaScript
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development