Forecasting the Asynchronous Behavior of Promises

I encountered a piece of code that left me puzzled about the flow of execution.

var x = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve([1, 2, 3]);
    }, 0);
  });
};

x().then((val) => {
  console.log(val);
}).catch((err) => {
  console.log(err.message);
});

console.log("hello");

for (var i = 0; i < 10; i++) {
  console.log(i);
}

var y = Promise.all([Promise.resolve(1), Promise.reject(Error("err"))]);

y.then((arr) => {
    console.log(arr);
  })
  .catch((err) => {
    console.log(err);
  });

Promise.resolve('ta-da!')
  .then((result) => {
    console.log('Step 2 received ' + result);
    return 'Greetings from step 2';
  })
  .then((result) => {
    console.log('Step 3 received ' + result);
  })
  .then((result) => {
    console.log('Step 4 received ' + result);
    return Promise.resolve('fulfilled value');
  })
  .then((result) => {
    console.log('Step 5 received ' + result);
    return Promise.resolve();
  })
  .then((result) => {
    console.log('Step 6 received ' + result);
  });

Below are the sequence of logs:

"hello"
0
1
2
3
4
5
6
7
8
9
"Step 2 received ta-da!"
"Step 3 received Greetings from step 2"
"err"
"Step 4 received undefined"
"Step 5 received fulfilled value"
"Step 6 received undefined"
[1, 2, 3]

The for loop behaves as expected. The setTimeout() operates as intended, and the promise resolves after the event loop.

The two other promises seem to clash, causing unexpected results. I anticipated the synchronous fulfillment of promises, leading to the following expected results:

"hello"
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    "err"
    "Step 2 received ta-da!"
    "Step 3 received Greetings from step 2"
    "Step 4 received undefined"
    "Step 5 received fulfilled value"
    "Step 6 received undefined"
    [1, 2, 3].

Although promises are resolved asynchronously, it's puzzling why they collide.

Refer to the attached screenshot.

https://i.sstatic.net/NunVd.png

Answer №1

In your code, there are three distinct promise chains:

  1. The first one begins with x() and takes the longest due to the timeout.
  2. The second one starts with y (from Promise.all(…)) where the error is thrown.
  3. The third one starts with Promise.resolve('ta-da!').

These chains do not wait for each other unless explicitly instructed to do so. They operate in an arbitrarily interleaved manner, similar to standard asynchronous functions (like two setIntervals with different periods).

The expectation was for the promises to be fulfilled immediately and synchronously.

However, Promise callbacks are always asynchronous, even if the promise is already resolved.

Answer №2

Instead of focusing on simplistic testing methods, I'll delve into a design perspective:

The primary purpose of promises is to handle asynchronous operations, such as server requests, concurrently.

Therefore, the sequencing of their resolution depends more on the responses received from the server rather than the client-side JavaScript loop in the browser.

Asynchronous requests are intentionally designed to be non-deterministic, a characteristic that applies to all asynchronous operations.

If you require sequential execution of requests, you must ensure that the previous promise is resolved before initiating the next one. However, for independent tasks like loading a dashboard with separate components, you can launch all asynchronous requests simultaneously without being concerned about the order of their resolution. In the context of the dashboard, does it truly matter if the first component loads before the second, especially when they display unrelated information? Likely not.

Regarding browser implementation, it's worth noting that the behavior may vary across different browsers, making it irrelevant to focus on a single browser. It is essential to ensure that your JavaScript code functions properly across multiple browsers.

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

Determine the identifier of the subsequent element located within the adjacent <div> using jQuery

I have a form with multiple input elements. While looping through some elements, I need to locate the id of the next element in the following div. You can find the complete code on jsfiddle $(":text[name^=sedan]").each(function(i){ var curTxtBox = $(thi ...

The system is unable to retrieve the value of the property which is set as null

I'm trying to figure out how to store the input value of name_enter into the variable userName. However, every time I attempt this, I encounter the following console error: Uncaught TypeError: Cannot read property 'value' of null function ...

How to locate the duplicate elements within an array using JavaScript

There are two different sets of numbers Numbers1=[ 0, 1, 2, 0, 2 ]; Numbers2=[ 0, 0, 1, 2, 2 ]; The goal is to determine the index of each element in Numbers2 from Numbers1 and create a new array like [0,3,1,2,4]; If you would like to see the code I wr ...

The resolution of all elements following an async/await within an Array.map() operation may not be guaranteed

In a previous post, I asked a question about running synchronous functions as promises. After converting them to asynchronous functions, the output now displays some null elements in the array. I am puzzled as to why this is happening. Here is a snippet o ...

Performing multiple ajax calls simultaneously in JavaScript using the React framework

Within my React application, I am faced with the challenge of handling an array of parameters (such as IDs) that need to be passed as parameters in a queue of ajax calls. The issue arises when this array exceeds 1000 items, causing the browser page to beco ...

Tips for choosing the desired test to execute with Nightwatch Programmatic API

Currently, I am in the process of developing a web application that enables me to execute Nightwatch tests through a visual interface. At this point, I have successfully been able to run all my tests using a post request from my web app utilizing the Nig ...

When attempting to make my styles responsive, I found that they broke due to duplicate classes on the landing page I was creating with next.js and styled components

Something strange is unfolding, and I find myself confused about the overall situation. Let me try to explain it the best I can. On my landing page, there are three different components: const Home = () => { return ( <> <Head> ...

The success function is failing to display the Ajax response

Is there a way to correctly display the ajax response of my code? I noticed that when using async=true, only the last value of yy is shown. However, I want to display it for all values from 0 to a. Interestingly, everything works fine when using async=fa ...

How can I retrieve the parent scope in an Angular UI nested named view?

One of the challenges I faced in my application was dealing with nested views within several screens. After experimenting with different approaches, I discovered that creating modal dialog boxes and sliding panels as actual nested states with corresponding ...

Exploring the Depths of Google Chrome: Unleashing the Power of

While a similar question has been posed previously, I am encountering difficulties debugging Javascript in Google Chrome. When I navigate to Page > Developer, the "Debug Javascript" function (Ctrl+Shift+L) is not active. Even trying Alt + ` does not se ...

A step-by-step guide to extracting live data using cheerio and socketio

I am currently scraping data from a website using Cheerio. Can someone provide me with guidance on how to retrieve web data and automatically update it using socket communication when there are changes on the website? I want to make this process real-tim ...

modifying the source of an Ajax POST request

Is it possible to modify the referrer in an HTTP Ajax call using jQuery or JavaScript? I'm looking to send a request from my page but have the referrer appear as though it came from another page. Any insights would be appreciated. ...

Create dynamic HTML files using Express, EJS, and FS, and deliver them using Nginx as the server instead of relying

Imagine a scenario where we have a JSON object: [ { "id": 1, "title": "Title 1", "description": "Description 1" }, { "id": 2, "title": "Title 2", ...

What could be causing the function to not execute before the rest of the code in the React App?

My lack of expertise may be the reason, but I'm unsure how to address this issue: Here's what I have: A button labeled "Check numbers" <Button fullWidth variant="contained" onClick={this.checkOptOut ...

Utilizing Azure SDK to send an email

In my Node.js project, I am currently utilizing azure-graph: const MsRest = require('ms-rest-azure'); const credentials = await MsRest.loginWithServicePrincipalSecret(keys.appId, keys.pass, keys.tenantId, { tokenAudience: 'graph' } ...

Utilizing a nested interface in Typescript allows for creating more complex and

My current interface is structured like this: export interface Foo { data?: Foo; bar?: boolean; } Depending on the scenario, data is used as foo.data.bar or foo.bar. However, when implementing the above interface, I encounter the error message: Prope ...

Create a discord.js bot that can randomly select and send a picture from a collection of images stored on my computer

I'm currently working on a bot that sends random pictures from an array of images stored on my computer. However, I encountered an issue when trying to embed the image, resulting in the following error message: C:\Users\47920\Desktop&bs ...

Expandable Grid Sections in React MUI

Is there a way to create a grid layout where items with showDefault: true are always displayed at the top, and then users can click an arrow button to expand the grid and also show the items with showDefault: false? Any suggestions on how to achieve this? ...

Can you confirm the mobile type, please? Using JavaScript to display a div only once based on the mobile type

Is there a correct way to determine the type of mobile device I'm using? Are there alternative methods to check for the mobile type? Take a look at my approach in the code below. How can I test this using a tool? Does anyone have insights on checki ...

Instructions on creating a function within the setState() function

This piece of code was created for a React application. The goal is to continuously add a certain number to the state every set interval when the 'AGGIUNGI JACK' button is clicked. However, upon clicking the button, an error message is displayed: ...