Is the order of execution alternating when resolving a promise from an external one?

As I was exploring the resolution of promises within one another, I came across some intriguing behavior:

const someTask = callback => {
  new Promise(res => res())
    .then(() => callback())
    .then(() => console.log("A 1!"))
    .then(() => console.log("A 2!"));
};

new Promise(res => someTask(res))
  .then(() => console.log("B 1!"))
  .then(() => console.log("B 2!"));

The resulting output is as follows:

B 1!
A 1!
B 2!
A 2!

Based on my initial expectations, I anticipated that:

  1. At minimum, one chain would be executed entirely before moving on to the next so all A's .then callbacks would run first followed by B's, or vice versa. However, they appear to alternate back and forth rather than executing in sequence.

  2. A's initial log statement would occur before B's since it resolved first.

I acknowledge that this may vary depending on implementation and that I shouldn't rely on execution order (my main concern in my project is ensuring A resolves B when necessary), but I am intrigued by the reasons behind this behavior. This applies to both native promises and Bluebird, with no difference in the outcome.

Answer №1

To avoid confusion, I will steer clear of technical jargon like EnqoeueJob.

When you use .then(() => { ... }), you are actually enqueueing a microtask. Microtasks always execute when there is only platform code remaining, making them the "last" to run before any I/O operations.

In your specific scenario:

  • All promise constructors execute synchronously, as usual.
  • Your then methods always run on a new microtick.

Therefore, in this case:

  1. The first promise constructor runs synchronously and calls someTask.
  2. someTask creates a promise and resolves it immediately.
  3. A microtick elapses, triggering the execution of the initial promise's then.
  4. The subsequent thens are scheduled for execution.
  5. These thens schedule additional thens, creating an alternating pattern.

This alternating pattern occurs because microticks simply get queued at the end of the microtask queue. While seemingly consistent, this behavior was not by design -- more of a coincidence or oversight during promises implementation. It is unsustainable to rely on this order of execution.

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

Change the size of the font with a slider in VueJS

I have been utilizing the project found at This particular project allows end-users to reuse Vue components as editable sections by providing a styler overlay for adjusting content within a div or section. After installation, I added a slider which now ap ...

Ajax call fails to trigger upon change

Currently, I am focusing on creating an HTML table with a form that contains a select element offering options for ALL and Biscuits. Initially, the table populates correctly upon loading. However, I am facing an issue when attempting to trigger an AJAX ca ...

What is the primary function for Express.js and Node.js 10 in Google Cloud Functions?

My Node JS version is 10 Express JS version: 4.16.1 I understand that for Node JS 8, the entry point should be "app" The generated code (from `npm install -g express-generator) www #!/usr/bin/env node /** * Module dependencies. */ var app = require( ...

Adjust image loading according to screen dimensions

I am working on HTML code that currently displays an image. The code looks like this: <div> <img id="wm01" alt="PP" title="PP" u="image" src="theImages/wm01.jpg" /> </div> My goal is to show a different image based on the screen si ...

Retrieving an image from an array

I attempted to design a slider for displaying my projects by creating an array to fetch information and insert it into HTML. However, I encountered difficulty in getting the images to change as only the text and heading were updating. Despite seeking assis ...

What is the best way to save the current time in a database using JavaScript in an ASP.NET application?

I positioned the Label outside the update panel so that any error or confirmation messages would be displayed on the top right side without reloading the entire page. However, the label is not displaying any text. When I comment out the update panel, it wo ...

"Node.js is malfunctioning when trying to respond with JSON data

After sending an '/init' request and receiving a response of {"x":50}, I proceed to make a '/user' request which returns {"x":50,"data":"jack"}. Everything seems fine so far. However, if I were to make another init request, it would onc ...

Validating Angular UI Route state with Protractor

I've been experimenting with the protractor framework to conduct tests on my angular application. Is it possible for me to verify the angular state during an end-to-end test? ...

Revolutionizing user experience: New feature seamlessly triggers button actions with the power of "enter"

I need assistance with modifying a form that contains two buttons and several text inputs. Currently, if the enter key is pressed, it triggers a click event on the first button. However, I want to modify this behavior so that if any of the text boxes are f ...

Ensuring that objects in a mongoose schema have unique pairs of elements

When creating a mongoose schema, I want to ensure that no two objects have the same combination of author's first name and last name. It is allowed for objects to share one, but not both. const authorShcema = new mongoose.Schema({ autherFirstName: ...

Navigating through the additional plugins in WebDriver

After installing a plugin in Chrome, the next step is to access it through webdriver. Here's how you can do it: File addonpath = new File("path of .crx file"); ChromeOptions chrome = new ChromeOptions(); chrome.addExtensions(addonpath); WebDriver dri ...

What is the best way to retrieve a response from a modal dialog using jQuery?

Is there a way to utilize an add-in such as simple-modal or the dialog add-in in the UI kit to achieve AJAX interaction with the server? I am looking for a solution that allows the modal to communicate with the server and return the result back to the ca ...

Halting execution: Trying to use the keyword 'import' which is not allowed here

0. April 2023: error cannot be reproduced anymore see here The error is no longer replicable due to bug fixes in react-scripts 5.0.1. 1 Even though the error is gone, the question and my self-answer still seem relevant to Angular users and others as we ...

Conditional rendering is effective for displaying a form item based on certain conditions, but it may not be as effective for

I want a textarea element to appear or disappear based on the selected state of the radio buttons before it. If "no" is chosen, the textarea will be hidden, and if "yes" is chosen, the textarea will become visible. <fieldset class="input-group form-che ...

What are the steps to implement OAuth authentication using AJAX and jQuery?

In my experience, I have had the opportunity to work with the Twitter web API using OAuth and a Python library, as well as experiment with the Instagram API using a small JavaScript library. Both APIs involve making web REST requests in the background, st ...

Various filters have been utilized on an array of objects

Within one of my Vue components, the code structure is as follows: <li class="comment" v-for="comment in comments"> ... </li> Accompanied by a computed method: computed: { comments() { // Here lies the logic for filtering comment ...

A controller in Angular.js that leverages several different services

I'm having trouble injecting multiple services into a controller. Here are my listed files: index.html file: <script src="'./angular/angular.min.js'></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta ...

Ensuring promise doesn't resolve until the IF STATEMENT is executed

I am encountering an issue with the "checkWorkflow" function where it seems to be executing the "If" statement before actually checking. This deduction is based on the output in my console, which makes me believe there might be a problem with how I am hand ...

Adjust the FlipClock time based on the attribute value

When setting up multiple FlipClock objects on a page, I need to retrieve an attribute from the HTML element. The specific HTML tag for the clock is: <span class="expire-clock" data-expire="2015-09-22"> Is there a way to access '2015-09-22&apos ...

Is it possible to pass a useState function to a component during its initialization?

Currently, I am utilizing the useState hook to effectively handle the rendering of components on the screen. My goal is to initialize it with a component while passing in the useState function to set the screen within the component. Below is my App.js fil ...