Promises and closures 😢‍🌫️

 A simple Promise

const getData = new Promise((resolvereject=> {
  reject('error');
  resolve('data');
});

getData.then((reserr=> console.log(res));
getData.catch((reserr=> console.log(res));

A promise can have resolve or reject

Same way when you read the response, you can have resolve or reject. You can read them both or you can have a separate catch function.

In the above example, we get "error" instead of "data" as it was rejected 1st

const getData = new Promise((resolvereject=> {
  resolve('data');
  reject('error');
});

getData.then((reserr=> console.log(res));
getData.catch((reserr=> console.log(res));

This will give "data" and not "error"


Static Functions of Promise

1. Promise.all

It waits for all promises to resolve and then give a single array with combined output

const getData1 = new Promise((resolvereject=> {
  resolve('data1');
  reject('error1');
});

const getData2 = new Promise((resolvereject=> {
  resolve('data2');
  reject('error2');
});

const getData3 = new Promise((resolvereject=> {
  resolve('data3');
  reject('error3');
});

Promise.all([getData1getData2getData3])
  .then((res=> {
    console.log(res);
  })
  .catch((error=> {
    console.log(error);
  });

Output: ["data1""data2""data3"]


If one of the promise rejects, the catch is executed and will not give the resolved value of other promises

const getData1 = new Promise((resolvereject=> {
  resolve('data1');
  reject('error1');
});

const getData2 = new Promise((resolvereject=> {

  //resolve('data2');

  reject('error2');
});

const getData3 = new Promise((resolvereject=> {
  resolve('data3');
  reject('error3');
});

Promise.all([getData1getData2getData3])
  .then((res=> {
    console.log(res);
  })
  .catch((error=> {
    console.log(error);
  });

Since getData2 is not resolving, but rejecting the output will be: "error2"

2. Promise.allSettled

This will will give the response of all promises irrespective of rejected or resolved. But just waits for all promises to be completed.

The same code with allSettled will give the below output:

[{…}{…}{…}]
  1. 0Object
  2. 1Object
  3. 2Object


3. Promise.race

Race will give the output of the 1st completed promise. Could be resolved or rejected

const getData1 = new Promise((resolvereject=> {
  resolve('data1');
  reject('error1');
});

const getData2 = new Promise((resolvereject=> {
  //resolve('data2');
  reject('error2');
});

const getData3 = new Promise((resolvereject=> {
  resolve('data3');
  reject('error3');
});

Promise.race([getData1getData2getData3])
  .then((res=> {
    console.log(res);
  })
  .catch((error=> {
    console.log(error);
  });

Output: data1

SetTimeouts Inside Promises

const getData1 = new Promise((resolvereject=> {
  setTimeout(resolve3000'data1');
});

getData1.then((res=> console.log(res));
getData1.catch((res=> console.log(res));

Here we are resolving 'data1' after 3 seconds. 

Output: data1

Dynamic Time for setTimeouts.

Just wrap it around a function and return the promise
function myFunction(time) {
  return new Promise((resolvereject=> {
    setTimeout(resolvetime'data1');
  });
}

let c = myFunction(1000);
c.then((res=> console.log(res));
c.catch((res=> console.log(res));

//output: data1 after 1 sec


Closures Returning Promises

Let us first recap what a closure is. Closure is a function that returns an inner function that has a cached value of the state of a variable on the outer function

A normal closure would look something like this:

function Outer() {
  let count = 0;
  return function inner() {
    count = count + 1;
    return count;
  };
}

let func = Outer();
func(); //1
func(); //2

Now, we need to return a promise instead of a regular function

function Outer() {
  let count = 0;
  return function inner() {
    return new Promise((resolvereject=> {
      count = count + 1;
      resolve(count)
    }) 
  }
}

let func = Outer();
func().then(res => console.log(res))
func().then(res => console.log(res))
func().then(res => console.log(res))
func().then(res => console.log(res))

Now we get the same output. You can send your own time for a setTimeout. Thus combining async, promise and closures


function Outer() {
  let count = 0;
  return function inner(time) {
    return new Promise((resolvereject=> {
      count = count + 1;
      setTimeout(resolvetimecount)
    }) 
  }
}

let func = Outer();
func(100).then(res => console.log(res+"called-1"))
func(200).then(res => console.log(res+"called-2"))
func(5).then(res => console.log(res+"called-3"))
func().then(res => console.log(res+"called-4"))


Guess the output!
Answer is below














it is:























































Comments

Popular posts from this blog

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

React & State Management: All Concepts

React: Communication between components