Enhancing JavaScript Asynchronous Programming with EventLoop and async/await

Exploring the intricacies of how JavaScript processes asynchronous methods led me to dive into async/await. In an effort to gain a complete understanding, I crafted the following example:

async function first() {
  console.log(9);
  await Promise.resolve(2).then((r) => console.log(r));
  console.log(0);
  await Promise.resolve(3).then((r) => console.log(r));
}

async function second() {
  console.log(10);
  await Promise.resolve(4).then((r) => console.log(r));
  console.log(11);
  await Promise.resolve(5).then((r) => console.log(r));
}
first();
second();
const promise = Promise.resolve("new Promise");
promise.then((str) => console.log(str));

//The output: 
//9
//10
//2
//4
//new Promise
//0
//11
//3
//5

Thus, it raises the question: what is the reasoning behind this sequence, and how does JavaScript's EventLoop interact with async/await?

I have attempted to replicate similar syntax in other examples, but the outcome remains consistent.

Answer №1

Presented here is a simplified timetable showcasing the most crucial evaluated expressions, the call stack at that moment, and the promise job queue (along with promise reactions):

Call Stack Evaluation Job Queue
Script first() -
Script>first console.log(9) -
Script>first Promise.resolve(2).then() (r=2)=>console.log(r)
Script>first await <pending> (r=2)=>console.log(r)
Script second() (r=2)=>console.log(r)
Script>second console.log(10) (r=2)=>console.log(r)
Script>second Promise.resolve(4).then() (r=2)=>console.log(r)

(r=4)=>console.log(r)
Script>second await <pending> (r=2)=>console.log(r)

(r=4)=>console.log(r)
Script
promise = Promise.resolve("new Promise")
(r=2)=>console.log(r)

(r=4)=>console.log(r)
Script
promise.then((str)=>console.log(str))
(r=2)=>console.log(r)

(r=4)=>console.log(r)

(str="new Promise")=> console.log(str)
Job (r=2)=>console.log(r) (r=4)=>console.log(r)

(str="new Promise")=> console.log(str)
Job>anonym console.log(2) (r=4)=>console.log(r)

(str="new Promise")=> console.log(str)


resume first()
Job (r=4)=>console.log(r)
(str="new Promise")=> console.log(str)


resume first()
Job>anonym console.log(4)
(str="new Promise")=> console.log(str)


resume first()

resume second()
Job
(str="new Promise")=> console.log(str)
resume first()

resume second()
Job>anonym
console.log("new Promise")
resume first()

resume second()
Job resume first() resume second()
Job>first console.log(0) resume second()
Job>first Promise.resolve(3).then() resume second()

(r=3)=>console.log(r)
Job>first await <pending> resume second()

(r=3)=>console.log(r)
Job resume second() (r=3)=>console.log(r)
Job>second console.log(11) (r=3)=>console.log(r)
Job>second Promise.resolve(5).then() (r=0)=>console.log(r)

(r=5)=>console.log(r)
Job>second await <pending> (r=3)=>console.log(r)

(r=5)=>console.log(r)
Job (r=3)=>console.log(r) (r=5)=>console.log(r)
Job>anonym console.log(3) (r=5)=>console.log(r)

resume first()
Job (r=5)=>console.log(r) resume first()
Job>anonym console.log(5) resume first()

resume second()
Job resum first() resume second()
Job>first - resume second()
Job resume second() -
Job>second - -

Key Points to Note:

  • When a then method is executed on a fulfilled promise, it adds a job to the queue. The script will complete execution before extracting and executing the first job in the promise queue.

  • Executing a then method creates a new pending promise even if called on a resolved promise. This pending promise only resolves after the callback is executed asynchronously via a job.

  • After an expression following an await is executed, the state of the async function is saved until the awaited promise resolves, restoring the running state through a queued job.

We hope this sheds light on some aspects for you.

Answer №2

This code snippet showcases the comparison between two async functions:

async function first() {
  console.log(9);
  await Promise.resolve(2).then((r) => console.log(r));
  console.log(0);
  await Promise.resolve(3).then((r) => console.log(r));
}

And its equivalent non-async function form:

function first() {
  console.log(9);
  return Promise.resolve(2).then((r) => console.log(r)).then(() => {
    console.log(0);
    return Promise.resolve(3).then((r) => console.log(r));
  });
}

Further illustrating similar functionality:

function first() {
  console.log(1);
  return Promise.resolve('a').then((r) => console.log(4, r)).then(() => {
    console.log(7);
    return Promise.resolve('b').then((r) => console.log(9, r));
  })
}

function second() {
  console.log(2);
  return Promise.resolve('c').then((r) => console.log(5, r)).then(() => {
    console.log(8);
    Promise.resolve('d').then((r) => console.log(10, r));
  })
}
first();
second();
console.log(3)
const promise = Promise.resolve('e');
promise.then((str) => console.log(6, str));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing $.when to merge AJAX requests and then passing the resulting data to a designated function

I am struggling with sending data between functions and using $.when in my JavaScript code. I have separate functions and AJAX calls that update content on the page, but they need to load together on page load. Despite trying various solutions to combine A ...

Issue with Bootstrap 5 Modal Overlay

I created a function that automatically generates a modal to save time and keep the code organized. This way, the HTML and JS related to the content of the modal are all in one PHP file, rather than mixed in with the file calling the modal: function new_mo ...

Sharing styles between ReactJS and Material-UI - best practices

I am currently facing an issue where I need to share styles across my entire web application. Here is the Problem: I have been using makeStyles in a repetitive manner as shown below: In component_A.js const useStyles = makeStyles({ specific_style: { ...

Steps for inserting a word into an element using jQuery

How can I use JQuery to insert English words into an element? Before: رایجترین نوع این پارامتر کلاس پایه eventArgs می باشد. After : رایجترین نوع این پارامتر کلاس پایه <bdo>eventArgs& ...

Cleaning up HTML5 video content

I have been on the search for a solution that would allow me to "scrub" through HTML5 video. So far, I have not come across one and was considering developing my own. However, before diving into that process, I wanted to seek advice from the community here ...

Issue: Error message - Unhandled promise rejection: NodeInjector error - ControlContainer not found

I'm having trouble validating a form and encountering an error. I tried implementing the suggestions provided in the following threads without success: Getting error suddenly in Angular Error: NodeInjector: NOT_FOUND [ControlContainer] Using forms i ...

Customize the CSS for material-ui buttons or create a new style altogether

Looking to customize the background color of a material UI RaisedButton, I have encountered a challenge. This is what I currently have: const style = { backgroundColor: 'green' }; export default class CreateLinksave extends React.Component { ...

Refreshing the three.js scene seamlessly within a single-page web application

I am currently working on a single page application that consists of multiple "slides," each implemented as a different hidden div, which becomes visible when it is the current slide. One of these slides features a canvas element and a ThreeJS scene. The ...

Including additional data to a page after each iteration in order to display the current progress

I am currently working on a loop that iterates through the lines of a text area and processes each line sequentially. However, I am facing an issue where the page becomes unresponsive until all the data has been processed. Is there a way to dynamically u ...

Managing JSON Forms using jQuery on Google's App Engine

Having difficulty getting jQuery to function properly on GAE in python 2.7. The main issue is that jQuery is unable to retrieve the json data sent by the server. A basic comment form with no special features: <form action="/postcomment/" method="post" ...

Steps for adding multiple images to a page in a React application:1. Create a

Having trouble displaying images on a React page. I have a directory with 30 images that I want to display on the page (.jsx file). Instead of exporting each image individually, is there a faster way to accomplish this task? Any ideas or suggestions would ...

Protractor troubleshooting: Issues preventing execution of protractor tests

My tests suddenly started throwing an error. Everything was working fine before this. Any advice on how to fix it? Here is my Config file: exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', allScriptsTimeout: 20000, baseU ...

Is it possible to capture a Browser TAB click event using JavaScript or AngularJS?

How can I trigger an event when returning to a tab? For instance: Let's say I have opened four tabs in the same browser with the same URL: such as: http://127.0.0.1:/blabla http://127.0.0.1:/blabla http://127.0.0.1:/blabla http://127.0.0.1:/blabla ...

How to organize initial, exit, and layout animations in Framer Motion (React) tutorial?

Currently, I am utilizing framer-motion library for animating a change in grid columns. This is the objective: Within the grid container (#db-wrapper), there are nine buttons arranged. https://i.stack.imgur.com/61pQqm.png When the user switches to the ...

The error message "The useRef React Hook cannot be invoked within a callback function" is displayed

I'm currently working on developing a scroll-to feature in Reactjs. My goal is to dynamically generate referenced IDs for various sections based on the elements within an array called 'labels'. import { useRef } from 'react'; cons ...

Steps to enable navigation to external pages from a ReactJS app

I am working on a simple ReactJS application: [Demo] [Source] I am trying to implement navigation within the app from external sources without refreshing the web page. This functionality should be similar to using this.props.history.push(...). /public/i ...

Issue with parameter functionality not working as expected

This code snippet is not functioning as expected. I am trying to extract and print the values from the URL parameter file:///C:/Users/laddi/Desktop/new%201.html?t=vindu&b=thind function GetURLParameterValue(param) { var pageURL = window. ...

Troubles with retrieving Array data for a JavaScript column chart

I am currently developing a Flask app in Python and utilizing render_template to send back 2 arrays, "names" and "deals", to my HTML file. I have confirmed that these arrays are working correctly based on the code snippet below that I tested, which display ...

Using the reduce method in JavaScript or TypeScript to manipulate arrays

Just exploring my culture. I have grasped the concept of the reduce principle var sumAll = function(...nums: number[]):void{ var sum = nums.reduce((a, b) => a + b , 0); document.write("sum: " + sum + "<br/>"); } sumAll(1,2,3,4,5); The r ...

Asynchronous operations and recursive functions in the world of Node.js

When working with express and mongoose, I frequently find myself needing to perform batch operations on collections. However, the typical approach involves callbacks in nodejs concurrency coding, which can be cumbersome. // given a collection C var i = 0 ...