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.