Promises on NodeJS

1

I'm learning Node and getting a bit of asynchronous programming. To learn, I got 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 was 1, 2, 3, and 4. But it leaves 1, 3, 4, 2 because of the asynchronous programming. I searched the internet and found some places quoting promises, but the examples I found of promise are a bit complex and I did not quite understand. I think it should not be difficult to solve this problem, but I do not find something very well explained. If someone can show me a code to solve this I would thank, thank you

    
asked by anonymous 29.03.2018 / 05:09

2 answers

0

The problem starts with the fact that 2 and 4 are written asynchronously, so if you let everything scroll normally it will be written at the end.

I'll start by saying that this example is still doable without Promises, but it's 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 have to realize what they are for and how they are used in simple scenarios. Imagine that you want to display a number on the console using a Promise and setTimeout so that writing is timed.

In this case you could do this:

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

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

Notice that Promise receives two callbacks a hit that is usually called resolve and an error usually called reject . When you make resolve within Promise you are executing the received function by passing the success value. Then we call .then passing the success function that is:

valor => console.log(valor)

It logs the received value. I have chosen to write with Arrow Function to be simpler and more compact, but it 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 completely without Arrow Functions:

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

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

Chaining Promisses

One of the main goals of Promises is to be able to chain multiple calls with then avoiding nesting. The nesting would be greater depending on how many threaded things you want to do. If any errors arise in any of the promises in the thread it 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, here's the hint that async and await are much easier to work by getting 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 will not go into details because @epx already gave an idea to follow this way.

    
29.03.2018 / 13:22
1

I have some ready-made examples that link two timers, hopefully useful. The first uses Promises, waiting a while, returning a random result and simulating flaws to 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 with the syntax async / await. Unfortunately, to wait for the result of an asynchronous function, it is also necessary that await is in of an async function, so the anonymous function:

(async () => {
        try {
                let x = await op1();
                let res = await op2(x);
                console.log("Sucess: " + res)
        } catch (err) {
                console.log("Error: " + err)
        }
})();
    
29.03.2018 / 05:20