Promises in Nodejs

Asked

Viewed 236 times

1

I’m learning Node and picking up some of the asynchronous programming. To learn, I took the following example

console.log("1");
setTimeout(function(){console.log("2");},3000);
console.log("3");
setTimeout(function(){console.log("4");},1000);

The output I wanted, is that it was 1, 2, 3, and 4. But it comes out 1, 3, 4, 2 because of asynchronous programming. I searched the Internet and found some places quoting Precedents, but the examples I found of Precedent are a little complex and I didn’t understand well. I believe that this problem should not be difficult to solve, but I did not find something very well explained. If anyone can show me a code to solve this I’d appreciate it, thank you

2 answers

1

I’ve got a couple of examples lined up, two timers, hopefully useful. The first uses Promises, waiting a while, returning a random result and simulating failures so you see what happens when the promise is not "fulfilled":

"use strict";

function op1()
{
        return new Promise((fulfill, reject) => {
                setTimeout(() => {
                        let n = Math.random();
                        if (n >= 0.75) {
                                reject("op1 failed");
                        } else {
                                fulfill(n);
                        }
                }, 1000);
        });
}

function op2(x)
{
        return new Promise((fulfill, reject) => {
                setTimeout(() => {
                        let n = Math.random();
                        if (n <= 0.25) {
                                reject("op2. failed");
                        } else {
                                fulfill(Math.floor(x / 0.75 * 1000));
                        }
                }, 1000);
        });
}

console.log("Start");

op1()
.then(op2)
.then((res) => {
        console.log("Sucess: " + res);
})
.catch((err) => {
        console.log("Error: " + err);
});

The end of the code can be replaced by the syntax async/await. Unfortunately, to wait (await) for the result of an asynchronous function, it is also necessary that await is within of an async function, hence the anonymous function:

(async () => {
        try {
                let x = await op1();
                let res = await op2(x);
                console.log("Sucess: " + res)
        } catch (err) {
                console.log("Error: " + err)
        }
})();
  • Friend, sorry to bother you, but in this case it executes op1, which takes a value Random, if it is greater than or equal to 0.75 it gives error, if not it gives a fullfill(n). What would this fullfill be? Thank you!

  • "Fulfill" means "fulfill", in the sense of "fulfill the promise". Actually it is a callback passed as parameter passed by Promise and the variable could have any other name, like "ok", "good", "fulfill", whatever you wish.

  • 1

    @Matheusrocha O Fulfill used in the example is what is most commonly called resolve in the common code with Promisses

1


The problem begins with the fact that the 2 and the 4 be written asynchronously, so if you let it all roll normally they will be written at the end.

I start by saying that this example is still doable without Promises, but it is not a scalable solution:

console.log("1");
setTimeout(() => {
    console.log("2");
    console.log("3");
    setTimeout(() => console.log("4"),1000);
},1500);

Simple example

Before you start with Promises, you need to understand what they’re for and how they’re used in really simple scenarios. Imagine you want to show a number on your console using a Promise and a setTimeout so that the writing is timed.

In that case I could do so:

const timer = new Promise((resolve, reject) => {
  setTimeout(() => resolve(10), 1000);
});

timer.then(valor => console.log(valor));

Notice that Promise gets two callbacks a success usually called resolve and an error commonly called reject. When does resolve within Promise is executing the received function by passing the success value. We then call the .then passing the success function that is:

valor => console.log(valor)

Which logs the received value. I chose to write with Arrow Function to be simpler and more compact, but can also be written with normal function:

timer.then(function(valor){ 
    console.log(valor); 
});

The same applies to the rest of the functions in the example. See the same example entirely without Arrow Functions:

const timer = new Promise(function(resolve, reject){
  setTimeout(function(){
    resolve(10)
  }, 1000);
});

timer.then(function(valor){
  console.log(valor)
});

Encadeando Promisses

One of the main goals of Promises is to be able to chain the various calls with then avoiding nesting. Nesting would be greater depending on the amount of chained things you want to do. If any error arises in any of the Precedents in the chain he will be caught by catch.

See the first example rewritten with Promises:

const timer2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("2"),1500);
});

console.log("1");
timer2.then(valor => {
  console.log(valor);
  console.log("3");
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve("4"),1000);
  });
}).
then(valor => console.log(valor));

Async and Await

Just as a final note, I leave here the tip that async and await are much easier to work, staying in a style closer to conventional when not working with asynchronous functions. It is important to first understand how Promises work because this alternative is based on them.

I won’t go into detail because @epx has already given an idea to go this way.

  • Wow, thank you so much for your answer, Isac, it was very enlightening, simple and objective. Very real work!

  • @Matheusrocha No problem, we’re here to help

Browser other questions tagged

You are not signed in. Login or sign up in order to post.