JavaScript Promises: the execution of then() functions is not synchronous

I seem to be making a mistake and I need some assistance in figuring out what it is.

Here is a simplified version of the code causing the issue:

function testTimer(time, msg,resolve){
console.log(arguments.callee.name);
window.setTimeout(
                function() {
                    console.log("MSG:", msg);
                    if(resolve !== undefined)
                        resolve(1);
                }, time * 1000);
}

new Promise(function(resolve, reject) {
    testTimer(1, 'ONE', resolve);
}).then(function(resolved){testTimer(9, 'TWO');}, function(rejected){alert("Rejected!", reject)})
.then(function(resolved){testTimer(1, 'THREE'); }, function(rejected){alert("Rejected!", reject)});

The expected output should be:

ONE
TWO
THREE

However, due to the different execution times of the two 'then' functions, I get:

ONE
THREE
TWO

My question is simple: How can I make the 'then' functions wait for each other?

Thank you for your help!

Answer №1

To ensure the function returns a promise only after the timeout has elapsed, you must follow this approach:

function timerTest(duration, message, resolve) {
    console.log(arguments.callee.name);
    window.setTimeout(function() {
        console.log("MESSAGE:", message);
        if(resolve !== undefined) {
            resolve(1);
        }
    }, duration * 1000);
}

new Promise(function(resolve, reject) {
        timerTest(1, 'ONE', resolve);
    }).then(
        function(resolved){
            // a promise is returned here, resolved by timerTest function
            // note that a resolve function is passed into it
            return new Promise(function(resolve) {
                timerTest(9, 'TWO', resolve);
            });
        },
        function(rejected){
            alert("Rejected!", reject)
        }
    )
    .then(
        function(resolved){timerTest(1, 'THREE'); },
        function(rejected){alert("Rejected!", reject)}
    );

Explanation of how it operates: The timerTest function, as defined, takes a callback as the third argument to be executed after the timer expires. This callback resolves a nested promise created in the second step, ensuring the third step only occurs after the second one has been resolved by the timer. This maintains the expected 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

How can I utilize a variable in a v-for loop as a label for a q-btn in Vue.js?

I have a list: myList = [1, 2, 3, 4, 5, 6, 7, 8, 9] I'd like to generate buttons using this list where the label corresponds to the number: <q-btn v-for="number in myList" v-bind:key="number" color="primary" label=&q ...

(Javascript - Arrays) Find the leftmost and rightmost connected characters

Looking for the leftmost and topmost connected '1' character in a 2D matrix? Find the most left & top connected '1' character Find the most right & bottom connected '1' character EDIT 2.0: To start, provide the coordina ...

Tips for distinguishing between 1 and 1.00 as equal, and 1.01 as not equal in Angular

How should the number 1 be treated when the decimals are zero, for example 1.000? In this case, an alert popup should appear indicating that the numbers are the same. The maximum length of the textbox should be 7 characters. For instance, 1 and 1.00000001 ...

Sending client-side data from app.js to specific components using NextJS

When working with traditional React, it's common practice to define the Routers at the entry point and pass the necessary props to specific components as needed. This allows for easy access to props since all components are clearly defined. For examp ...

Engage with and rearrange JSON data

Upon receiving data from the endpoint, I realized that it needed some modifications before being suitable for display in a table. The initial example data looks like this: const data = [ { Year: 2017, OriginalIntBalanceOverdue: 0.0, D ...

"Automate the process of manual content duplication with JavaScript's for each replacement

Seeking a solution to automate the selection process without writing individual JS scripts for every input. For instance, having 10 double inputs (total of 20 inputs) and utilizing the each() function or other methods by only declaring selectors. Find th ...

Is it possible to enable a button as soon as input is entered?

I'm encountering a minor issue with my button's functionality. I am attempting to have the button enabled as soon as text input is entered into the text field, but currently it only becomes enabled after the focus has changed from the text field. ...

Differences between Cypress and JQuery objects, and the significance of the cy.wrap function

Currently diving into cypress and experimenting with various testing methods. If anyone could lend me a hand with the following inquiries: 1. I've come to understand that most cypress objects utilize jQuery objects for DOM operations, but what sets t ...

Guide to importing a JavaScript module as any type without using a declaration file (d.ts)

Looking to bring a js module into my ts app. Is there a way to achieve this without creating a d.ts file? If not, how can it be declared as any in the d.ts file? Currently using //@ts-ignore to ignore the error. Appreciate any help! ...

Having issues with JavaScript function returning value from Ajax request

My AJAX request function is functioning well - returning 1 for success and 2 for failure. However, I am facing an issue when trying to perform actions outside of this function based on the return value. Instead of getting either 1 or 2, I always receive "u ...

Error: Cannot access the 'top' property of an undefined object

Here is a snippet of my jQuery code: $(document).ready(function(){ $('.content-nav a').on('click',function(){ var str = $(this).attr("href"); var the_id = str.substr(1); $("#container").animate({ scrollTop: $ ...

Create a new array in JavaScript by comparing and finding the differences between two existing arrays

I have two arrays - array1 and array2. I want to compare both arrays and create a new array (array3) with values that are unique to array1. For example, 'mob2', 'pin', 'address2', 'city' are present in array1 but no ...

Error: Unexpected syntax error in JSON parsing after importing PHP file

Encountered an unexpected error: Uncaught SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data site:stackoverflow.com, which is appearing in the Firefox debug console. On my website, I have a form that triggers this function o ...

Create a list that starts with a header determined by an object's attribute within an array

Currently in Vue, I am attempting to create a list based on a specific property within an object. The array being retrieved from the vuex store is structured as follows: const array = [ { name: "British title string" nationality: "British" }, { ...

Form an item using an array

Is there a way to efficiently convert this array into a map? Here is how the array looks: var array = [{ "id" : 123 }, { "id" : 456 }, { "id" : 789 }]; The desired output should be: var result = { "123": { id: 123 } , "456": { id: 456 } , ...

My JavaScript if-else statement isn't functioning properly

I'm facing an issue with my if statement not functioning correctly when trying to validate non-numeric inputs for the weight variable upon submission. What could be causing this problem? submitBtn.onclick = function(){ var name = document.get ...

Failure to display updated property value

After rendering an array of objects, I am attempting to add a new property using a function. However, the new property value is not displaying on the page even though it is present when I log the object in the console. The new property that I want to add ...

Instructions on converting XML data obtained from an AJAX call into a downloadable file

I've been struggling with converting an AJAX response containing XML text into a downloadable file. I've tried various methods but haven't had success. In the past, I was able to work with a similar scenario involving a pdf, where the conte ...

Building an array of objects using a foreach loop

i am struggling to create an array of objects from two input groups, each group consists of 3 inputs with data-side attributes set to left or right every input has a class named "elm" and a data-pos attribute set to a, b, or c <input class="elm-left elm ...

How can I activate the socket.io connection event in NodeJS?

I'm currently experimenting with socket.io on NodeJS and I am facing a challenge in figuring out how to activate the socket solely from NodeJS. Previously, I have been using socket.io by invoking it from the front end. However, I am curious if it is ...