What is causing the behavior of this JavaScript code in the Execution Context?

I recently delved into the world of asynchronous programming in JavaScript and wanted to share some code for examination:

const myPromise = () => Promise.resolve('Success!');

function firstFunction() {
  myPromise().then(res => console.log(res));
  console.log('firstFunction');
}

async function secondFunction() {
  console.log(await myPromise());
  console.log('secondFunction');
}

firstFunction();
secondFunction();

The above code will yield the following output:

  • firstFunction
  • Success!
  • Success!
  • secondFunction

I am satisfied with the results and have a good understanding of why this sequence occurs:

  • FirstFunction() is added to the call stack
  • The promise is deferred on the event loop
  • console.log('firstFunction') executes and displays (firstFunction)
  • With the call stack empty, the resolved promise prints (Success!)
  • Next, SecondFunction() enters the call stack
  • Using async await means the code pauses at myPromise()
  • (Success!) is then displayed
  • Followed by (secondFunction)

If I modify the initial code as follows:

const myPromise = () => Promise.resolve('Success!');

function sayHi() {
  console.log('hi');
}

function firstFunction() {
  myPromise().then(res => console.log(res));
  console.log('firstFunction');
}

async function secondFunction() {
  console.log(await myPromise());
  console.log('secondFunction');
}

firstFunction();
secondFunction();
sayHi();

I would anticipate the following output:

  • firstFunction
  • Success!
  • Success!
  • secondFunction
  • hi

However, the actual output is:

  • firstFunction
  • hi
  • Success!
  • Success!
  • secondFunction

Could someone please clarify why this behavior is observed?

Answer №1

If we want the message queue to process the stored messages (from asynchronous functions), it is crucial that the call stack is clear.

You might find this article on the event loop helpful in understanding this concept.

In a scenario where the call stack contains 3 functions that must be executed and removed before the messages in the message queue are processed, the output of hi will appear prior to the execution of any async calls.

The reason secondFunction is executed last is because it is located within an async function with an await statement preceding it.

Answer №2

Consider the scenario with the following numbers:

1 - runFunction()

2 - executeFunction();

3 - greetUser();

The greeting 'Hello' appears second on the list because it reaches number 3 faster than resolving promises. The console.log() in number 1 executes immediately without waiting for a promise, which causes it to appear before the 'Hello' message.

All three functions, 1, 2, and 3, are executed, but due to the delayed resolution of promises in 1 and 2, the 'Hello' message is displayed before any promise-based console logs.

Answer №3

Explanation with notes:

function startFunction() {
  fetchUserData().then(result => console.log(result)); // This console.log will only execute 
                                                       // after the data is fetched
  console.log('startFunction');                        // This console.log will be printed
                                                       // immediately after fetchUserData() call
}

async function nextFunction() {
  console.log(await fetchUserData()); // No logging until data is fetched
  console.log('nextFunction');        // Following line waits for `await` to complete
}

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

Navigating a Bootstrap modal using arrow keys for scrolling - up and down

I attempted to address this issue by using the following code: // here, 'this' represents the modal $(this).focus(); Despite trying the above solution and even attempting to trigger a click event on it, I was unable to get it to work! UPDATE ...

Is there a way to set the menu to automatically open when the page loads?

Looking for some help with a slide out menu that I want to be always open and cannot be closed. I tried changing the open=true setting to open=false but it didn't work as expected. Here's the code snippet below. I aim to remove the open and close ...

The information is not appearing in the dropdown menu

The select tag for chapters is not displaying the result from the query properly. Instead of showing in the select tag, the chapter names are being displayed as echo statements. <!doctype html> <html> <head> <meta charset="utf-8"> ...

How can we stop the jumping of images in the grid? Is there a way to eliminate the jump effect?

Here is a script I am working with: <script src="http://static.tumblr.com/mviqmwg/XyYn59y3a/jquery.photoset-grid.min.js"></script> <script> $(document).ready(function() { $('.photoset-grid').photose ...

React Native Router Flux encountered duplicate keys in two children

Version(s) react-native-router-flux v3.31.2 react-native v15.2.1 I am encountering an issue when trying to call Actions.dialog() multiple times and receiving an error message. Despite attempting the fix mentioned in https://github.com/aksonov/react-nat ...

The error encountered is an unhandled rejection with a message stating "TypeError: Cannot access property 'username' of null

My tech stack includes NodeJS, PassportJS, MySQL, and Sequelize (ORM for MySQL). The following code snippet is taken from my Passport.JS file. Whenever a user registers on my website, an error is returned if the username or email is already in use. If both ...

terminate a node-cron task or abort a node-scheduler job

I'm currently working on a nodejs project that involves managing multiple cron jobs. However, I've encountered an issue when attempting to cancel these jobs. Here's the scenario: I have set up several cron jobs using node-cron or node-sch ...

Experiencing a strange response while attempting to parse the result of an Angular 2 HTTP JSON request

After successfully implementing the http.get call and retrieving data from the request, I encountered an issue: this.http.get('https://data.cityofnewyork.us/resource/xx67-kt59.json').subscribe(data => { // Read the result field from the ...

What is the process for modifying the logfile path in phantomjs using selenium?

Is there a way to modify the default --webdriver-logfile parameter that selenium passes to phantomjs when using them together? This is the line in the selenium log: 11:06:06.960 INFO - arguments: [--webdriver=14380, --webdriver-logfile=<ROOT PATH DELE ...

Error occurred during download or resource does not meet image format requirements

Encountering an issue when attempting to utilize the icon specified in the Manifest: http://localhost:3000/logo192.png (Download error or invalid image resource) from the console? import React from 'react'; import Logo from '../Images/logo1 ...

When using ngClick with a parameter, the parameter is not being successfully passed

My table resembles a tree structure with two ng-repeats. <table> <tr ng-repeat-start="am in anArray"> <td><button ng-click="TheFunction(am)"></button></td> </tr> <tr ng-repeat-start="em in anotherArray"> < ...

Setting a background image as a variable in Vue.js

I am currently working on a vue.js component that includes a div.icon: Vue.component('obj', { props: ['img', 'name'], template: '<div><div class="icon"></div> {{ name }}</div>' }) While ...

Ensure that the text is wrapped properly when implementing innerHTML functionality

Within my Angular 5 application, I am faced with a requirement to display HTML content retrieved from a database. An example of the text stored in the database is: <div><u>Documents and Files</u></div><ul><li>These docu ...

Guide to sending data from an HTML page to a MVC Controller using WebApi

How can I fix the issue with my HTML button not calling the API properly? function saveclickdata() { var allData = { InvNo:document.getElementById('TbInvNo').value, GrossSale:document.getElementById('Tb ...

Comparing XDomainRequest and XMLHTTPRequest - which one to choose

Our team is currently developing an application utilizing PixiJS that integrates a dynamic json loader. The .json files are loaded using the following logic: if(window.XDomainRequest) { this.ajaxRequest = new window.XDomainRequest(); } else if (windo ...

Troubleshooting issue in App component while utilizing React-Redux's 'connect' function

Upon attempting to utilize the connect() function provided by react-redux, I encountered the following error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the r ...

Utilize PHP to import an HTML file with JavaScript code into MySQL database

I've been attempting to use JavaScript to retrieve my location, but I'm facing an issue where when I click submit, the data is not getting entered into the page action.php. geolocation.php <form action="action.php" method="post"> < ...

Determine the number of items in an array with JavaScript in Node

Looking to create a new variable that counts the names in an array and assigns them accordingly? I'm currently stuck on this task. The array contains names: names = [Jan, Jan, Jana] Counting the names is simple, but I'm facing difficulty in org ...

When using Rails to render a JSON page remotely, the JavaScript AJAX handler fails to capture the response

My goal is to have a form that can post remotely and then receive JSON data back for my JavaScript to process. Below is the code I am using: <%= form_tag '/admin/order_lookup', remote: true, authenticity_token: true, id: "order-lookup-submit" ...

Is it necessary to reload the page each time to see updates on the navbar in nextjs?

I recently developed a Next.js application with a Navbar component integrated into my layout.tsx file. The challenge arises when a user logs in and is redirected to the home page, which showcases a link in the Navbar for viewing their profile. However, I n ...