async await | Namaste JavaScript - Season 02 - Ep 04

async await | Namaste JavaScript - Season 02 - Ep 04

Introduction to Async/Await

Overview of the Topic

  • The session focuses on understanding async/await, a crucial topic for JavaScript developers, beneficial for daily coding and interviews.
  • Key areas of discussion include definitions of async and await, their workings behind the scenes, real-life examples, error handling, interview preparation, and comparisons with traditional promises.

Understanding Async Functions

Definition and Characteristics

  • An async function is defined using the keyword async before a function declaration.
  • A critical property of an async function is that it always returns a promise. This is fundamental to its behavior in JavaScript.

Return Values

  • If an async function returns a non-promise value (e.g., string or number), it automatically wraps this value in a promise before returning.
  • For example, returning the string "Namaste" from an async function results in a fulfilled promise containing that string.

Working with Promises

Extracting Data from Promises

  • To access data from the returned promise, you can use the .then() method. This allows you to handle the resolved value effectively.
  • Using .then(), you can log or manipulate the resolved data; for instance, logging "Namaste" after resolving the promise.

Key Takeaways about Async Functions

Summary Points

  • Remember that all async functions return promises—this is essential knowledge for interviews.
  • If no explicit promise is returned by an async function, any returned value will be wrapped in a promise automatically.

Creating Promises within Async Functions

Example Implementation

Understanding Promises and Async/Await in JavaScript

Creating a Basic Promise

  • A new promise is introduced with resolve and reject methods. The example demonstrates creating a simple promise that resolves with a string value called "promise result value."
  • When returning this promise, it will not be wrapped in another promise if the return value is already a promise; it will be returned as-is.
  • The data from the resolved promise can be accessed directly when calling the function that returns it, allowing for straightforward handling of promises.
  • Using .then() on the returned promise allows logging of the resolved value, demonstrating how to access data from promises effectively.

Introduction to Async/Await

  • The discussion transitions to async functions and how they simplify working with promises, emphasizing their importance in modern JavaScript development.
  • The speaker prepares to explain how async/await works together to handle promises more intuitively than traditional methods.

Handling Promises Before Async/Await

  • An overview of handling promises before async/await is provided, highlighting the need for understanding previous methods for comparison.
  • A normal function (not async) is used as an example where .then() is employed to manage promises, illustrating basic usage patterns.

Transitioning to Async Functions

  • The speaker introduces an async function named handlePromise, explaining its role in managing asynchronous operations more efficiently than traditional approaches.
  • To handle a promise within an async function, the keyword await must precede the promise call. This marks a significant shift in syntax and approach.

Utilizing Await Keyword

  • The principle behind using await involves placing it before a promise so that execution pauses until the promise resolves, simplifying code readability.
  • Upon resolving the awaited promise, its value can be stored in a variable (e.g., Val), which can then be logged or manipulated further without chaining .then().

Key Takeaways about Async/Await

Understanding Async/Await in JavaScript

Introduction to Async/Await

  • The await keyword can only be used inside an async function; using it outside will result in a syntax error.
  • The await keyword is placed before a promise, allowing the code to pause until the promise resolves.

Difference Between Promise Handling Methods

  • A significant distinction exists between handling promises traditionally and using async/await, which simplifies asynchronous code.
  • To illustrate this difference, the speaker modifies a promise to simulate a longer execution time, akin to real-world scenarios like API calls.

Simulating Delayed Promise Resolution

  • A promise is created that resolves after 10 seconds, demonstrating how asynchronous operations do not complete immediately.
  • The use of setTimeout simulates delay in resolving the promise, emphasizing that promises represent operations that take time.

Observing Console Output with Traditional Promises

  • When using traditional promise handling, console output shows "Namaste JavaScript" first, followed by "promise resolved value" after 10 seconds.
  • This behavior illustrates that JavaScript does not wait for promises to resolve before moving on to subsequent lines of code.

Common Misunderstandings About Promises

  • Many developers mistakenly believe that JavaScript waits at certain points for promises to resolve; however, it continues executing subsequent lines immediately.
  • This misunderstanding can lead to confusion about when outputs appear in the console during asynchronous operations.

Transitioning to Async/Await

  • The speaker prepares to demonstrate how async/await changes this behavior and clarifies misconceptions about timing and execution flow.

Understanding Async/Await in JavaScript

The Behavior of Promises with Async/Await

  • The speaker introduces the concept of async/await, explaining that the expected output ("Namaste JavaScript") will not appear immediately after a promise is resolved. Instead, it highlights a common misunderstanding among developers regarding how async functions operate.
  • Initially, nothing appears in the console until 10 seconds have passed. After this delay, both "Namaste JavaScript" and the resolved promise value are printed, demonstrating that the JS engine waits for promises to resolve before proceeding.
  • The JS engine pauses execution at line 20 while waiting for the promise to resolve. Only after resolution does it continue to line 23, emphasizing that async/await allows for synchronous-like behavior in asynchronous code.
  • A key distinction is made: unlike traditional promise handling where execution continues without waiting, async/await causes the program to pause at specific points until promises are fulfilled.
  • The speaker poses a question about adding a console log before an await statement. This log ("hello world") prints immediately before the program waits for 10 seconds to resolve subsequent promises.

Exploring Multiple Await Statements

  • The discussion shifts towards executing multiple await statements within a function. The speaker prompts viewers to consider whether these awaits will execute sequentially or concurrently when resolving values multiple times.
  • Viewers are encouraged to think critically about how two await statements might affect execution order and timing—whether they would wait separately or run in parallel.
  • Emphasizing interview preparation, the speaker suggests understanding these concepts deeply can help answer complex questions during technical interviews confidently.

Complex Promise Scenarios

  • Upon refreshing the page after implementing two await statements, "hello world" prints first followed by both resolved values after 10 seconds—demonstrating that all awaited promises can be handled together rather than sequentially waiting for each one individually.
  • To further complicate matters, two separate promises (P1 and P2), with different resolutions (10 seconds and 5 seconds respectively), are introduced. This sets up an interesting scenario regarding their execution order.
  • Questions arise about how these two promises will behave: Will they print sequentially based on their individual timers or simultaneously? This uncertainty reflects common confusion surrounding asynchronous programming in JavaScript.

Understanding Promises in JavaScript: Execution and Behavior

Introduction to Promise Behavior

  • The speaker encourages viewers to engage with the content by liking the video, indicating that viewer interaction motivates further content creation.
  • A demonstration shows that even though a promise resolves in five seconds, subsequent console logs wait for ten seconds before executing, highlighting asynchronous behavior.
  • The async function appears to wait for all promises to complete before logging results, prompting questions about how this process works.

Reversing Promise Order

  • The speaker changes the order of promises (P1 = 5 seconds, P2 = 10 seconds), inviting viewers to predict the output based on this new configuration.
  • After refreshing the page, it is shown that after five seconds, only the first promise resolves and prints; after ten seconds, both outputs are printed sequentially.
  • This reversal of order leads to different execution behavior, emphasizing common confusion surrounding promise execution in JavaScript.

Behind-the-Scenes of Promise Execution

  • The speaker clarifies that while it seems like the JS engine waits for promises to resolve, it does not actually block or consume memory during this time.
  • If the JS engine were truly waiting on promises within the call stack, it would freeze; however, this is not what occurs during execution.

How Async Functions Operate

  • An explanation follows regarding how async functions operate line by line due to JavaScript's single-threaded nature.
  • The speaker plans to demonstrate how these functions execute using debugging tools available in developer consoles.

Exploring Call Stack Dynamics

  • A visual representation of the call stack is introduced as a critical component where function executions occur sequentially.
  • Debug points are set up at key moments in code execution (after each promise), allowing viewers to observe real-time behavior within the call stack.

Conclusion on Promise Handling

Understanding JavaScript's Asynchronous Behavior

Execution Flow in JavaScript

  • JavaScript is a synchronous, single-threaded language with one call stack, executing lines of code sequentially. The first line executed logs "hello world" to the console.
  • Upon reaching an await statement (e.g., await P1), the execution of the function suspends. This means that JavaScript does not wait for promises to resolve but allows other events to execute.
  • When an await is encountered, the function's execution is suspended without blocking the main thread, allowing other operations to continue running in the call stack.
  • The function remains suspended until the promise (P1) resolves. Once resolved after 5 seconds, it resumes execution from where it left off.

Promise Resolution and Function Resumption

  • After 5 seconds, when P1 resolves, control returns to the suspended function which continues executing from line number 29 and logs "Namaste JavaScript".
  • At this point, it checks if another promise (P2) has resolved. Since P2 takes longer (10 seconds), it again suspends execution without blocking.
  • The function will remain out of the call stack until P2 resolves after 10 seconds. Once resolved, it resumes at line number 33 and logs "Namaste JavaScript 2".

Summary of Execution Timing

  • The sequence of logging occurs as follows: "hello world" immediately; then after 5 seconds "Namaste JavaScript"; finally after another 10 seconds "Namaste JavaScript 2".
  • It's crucial to understand that while promises are being awaited, the JavaScript engine continues executing other tasks rather than waiting idly in the call stack.

Importance of Understanding Async Behavior

  • Recognizing how functions suspend during promise resolution is vital for mastering asynchronous programming in JavaScript. This concept often goes unaddressed in typical learning resources.
  • The speaker emphasizes sharing this knowledge widely among developers as understanding async behavior can significantly enhance coding practices.

Reverse Example for Clarity

  • A reverse scenario is presented where P1 takes longer (10 seconds), while P2 resolves faster (5 seconds).
  • In this case, "hello world" prints immediately; however, since P1 isn't resolved yet after its duration elapses (10 seconds), execution suspends until completion before moving on to check P2.

Understanding Async/Await in JavaScript

How Async Functions Work

  • The async function execution begins, and after a delay of 10 seconds, it prints "Namaste JavaScript" along with other values. This illustrates the non-blocking nature of async functions.
  • Developers often perceive that JavaScript pauses execution at certain points; however, it continues processing other tasks while waiting for promises to resolve.
  • During the wait time (e.g., 10 seconds), if there are additional events or functions triggered, they will be handled without blocking the call stack.
  • The call stack remains unblocked, allowing JavaScript to manage multiple operations simultaneously, showcasing its efficiency.

Demonstrating Call Stack Behavior

  • A demonstration is set up with promises resolving at different intervals (5 seconds and 10 seconds). The behavior of the call stack during these waits is observed.
  • After saving changes to the code, it's noted that the call stack appears empty after initial promise resolutions. This emphasizes how asynchronous operations do not halt program execution.
  • Further testing shows that after 20 seconds, another promise resolves and updates the console output accordingly.

Behind-the-Scenes Mechanics

  • A longer wait (20 and 40 seconds) is introduced to illustrate how async/await operates behind the scenes without freezing program execution.
  • After waiting for specified durations, console logs demonstrate how promises are managed within the call stack without interruption to user interactions or other processes.

Simplifying Complex Concepts

  • It’s explained that while function executions may seem suspended, JavaScript tracks ongoing processes efficiently. Developers can focus on writing code rather than managing these complexities directly.
  • The beauty of JavaScript lies in its ability to handle intricate asynchronous operations seamlessly while allowing developers to utilize simple syntax like async and await.

Practical Application: Fetch API Example

  • Transitioning from theoretical concepts to practical coding examples using fetch calls demonstrates real-world applications of async/await in making API requests.

Understanding Fetch API in JavaScript

Introduction to the GitHub User API

  • The speaker introduces the GitHub User API, explaining that it retrieves information about a specific user by using their username. For example, using "Akshay Mark 7th" as a user ID will return account details.

Making an API Call

  • The speaker outlines how to make an API call using the defined URL and emphasizes the importance of wrapping the URL string in double quotes for proper syntax.

Understanding Fetch Functionality

  • A discussion on how many developers may not fully understand how the fetch function operates. The speaker expresses concern over this knowledge gap among JavaScript developers.
  • It is explained that calling fetch returns a promise, which must be handled correctly using async/await syntax. This ensures that code execution waits for the promise to resolve before proceeding.

Handling Promises with Async/Await

  • The use of await is highlighted as essential for pausing function execution until the promise from fetch resolves, allowing access to returned data.
  • The fetch function returns a response object upon resolution, which contains important data regarding the request made.

Response Object and Readable Streams

  • The response object includes a body that is described as a readable stream. This stream can be converted into JSON format or other types depending on requirements.
  • To convert this readable stream into JSON, one must use .json(), which also returns a promise that needs to be awaited for successful resolution.

Recap of Fetch Process

  • A recap emphasizes that after fetching data and converting it to JSON, developers can log this data or manipulate it further within their applications.
  • The speaker contrasts two common methods of handling fetch responses: using async/await versus chaining .then() calls, noting both approaches ultimately achieve similar results but differ in syntax style.

Conclusion on Fetch Usage

  • Emphasizing practical application, the speaker encourages viewers to take notes and understand how these concepts apply when making actual API calls in their projects.

Understanding Async/Await and Error Handling in JavaScript

Execution Flow of Async Functions

  • The network call took 466 milliseconds to complete, demonstrating the asynchronous nature of JavaScript.
  • The handlePromise function execution is suspended while waiting for the promise to resolve, highlighting how async functions manage execution flow.
  • Once the promise resolves, the JSON value is logged to the console, illustrating how data retrieval works behind the scenes.

Error Handling with Try/Catch

  • To handle errors in async functions, wrap API calls within a try block instead of using .catch().
  • If an API call fails (e.g., due to an invalid URL), control jumps directly to the catch block without executing subsequent lines.
  • Errors can be managed by logging them or redirecting users based on specific conditions, showcasing flexibility in error handling strategies.

Alternative Error Handling Methods

  • An alternative method involves using .catch() on promises returned from async functions for error management.
  • Both try/catch and traditional promise handling methods are valid; developers can choose based on personal preference or project requirements.

Interview Preparation Tips

  • When asked about async/await in interviews, clarify that async is a keyword used with functions and that await can only be used inside these functions.
  • Explain how async/await simplifies working with promises and enhances code readability compared to traditional methods.

Understanding Promises and Async/Await in JavaScript

The Importance of Promises

  • Promises are fundamental in JavaScript, particularly for handling asynchronous operations. Understanding how to manage promises is crucial for technical interviews.
  • Candidates should be prepared to explain the workings of promises in detail during interviews, including how promise execution can be suspended.

Async/Await vs. Then/Catch

  • Async/await is essentially syntactic sugar over the traditional .then() and .catch() methods used with promises.
  • Despite being a different syntax, async/await operates under the same principles as native promise methods, maintaining the underlying mechanics of promise handling.

Advantages of Using Async/Await

  • Both async/await and .then()/.catch() have their merits; however, async/await simplifies code readability by reducing callback complexity.
  • With async/await, there’s no need for extensive promise chaining (e.g., fetch().then().then()), making it easier to follow the flow of asynchronous code.

Personal Preference and Best Practices

  • The speaker recommends using async/await whenever possible due to its clarity and ease of debugging compared to traditional promise handling.
  • While both methods can handle errors effectively, async/await is preferred for managing promises because it aligns better with modern coding practices.

Future Content and Courses

  • The speaker invites viewers to suggest topics for future videos on promises and related subjects as part of an ongoing series called "Namaste JavaScript."
  • Additionally, a new paid course titled "Namaste React" has been launched for those interested in learning React from the speaker's teaching style.
Video description

Wanna dive deep into React JS with me? Checkout Namaste React - https://namastedev.com/namaste-react/?version=2 Use coupon code : CODE72 and register now by link below. Only valid for first 500 students. Running heavy discounts right now, register today! async and await are keywords in JavaScript that are used to work with asynchronous code, making it easier to handle asynchronous operations like network requests, file I/O, or timers in a more synchronous-like manner, which can make your code more readable and maintainable. 00:00 - Introduction 01:08 - What is async in JS 15:15 - Using Await with async 21:48 - Diving deep into async/await 40:43 - Behind the scenes of async await 55:09 - Real world examples 01:04: 28 - Error Handling 01:09:00 - interview Tips 01:11:03 - async await vs promise then/catch If this video was helpful, give it a thumbs up and subscribe to my channel for more such videos. 🔔 Link to Subscribe: https://www.youtube.com/c/akshaymarch7?sub_confirmation=1 If you want me to cover any specific topic, then comment down below. I would be happy to help you. Cheers, Akshay Saini http://akshaysaini.in Stay Connected: LinkedIn - https://www.linkedin.com/in/akshaymarch7 Facebook - https://www.facebook.com/akshaymarch7 Instagram - https://www.instagram.com/akshaymarch7 Twitter - https://twitter.com/akshaymarch7 #Javascript #JavascriptInterviewQuestions #AkshaySaini