😎 Chillin' with JavaScript Promises: A Casual Chat on Async Awesomeness!

Photo by NEOM on Unsplash

😎 Chillin' with JavaScript Promises: A Casual Chat on Async Awesomeness!

Alright, let's loosen up a bit and chat about promises in JavaScript in a more casual way! πŸ‘―

So, you know how JavaScript has this whole async thing going on, right? Enter promises, the cool cats that make handling asynchronous stuff a breeze.

3️⃣ Three States to Rule Them All

Picture this πŸ“Έ: a promise is like a superhero that can be in one of three states – pending (just chillin'), fulfilled (mission accomplished), or rejected (oops, something went wrong).

Now, let’s say you have this async operation, like fetching data. You wrap it in a promise. If it's a success, you resolve it; if not, you reject it.

const fetchData = new Promise((resolve, reject) => {
  // Async stuff happens here
  const success = true;

  if (success) {
    resolve('Got the goods!');
  } else {
    reject('Epic fail!');
    }
});
πŸ’‘
What to play around with this code? Check out this link!

🍼 Consuming Promises: then & catch Showtime

Time to consume that promise! If it's all good, you celebrate with then πŸŽ‰. If things go south, you console.error with catch.

fetchData
  .then((data) => {
    console.log(data); // Woo! Got the goods!
  })
  .catch((error) => {
    console.error(error); // Uh-oh, something went wrong!
  });
πŸ’‘
What to play around with this code? Check out this link!

⛓️ Channing: Like Story Time for Promises

Promises can be like a story. One chapter leads to the next πŸ“•. Chain promises to do things sequentially. But remember 🧠, the next promise will not be called if the previous rejected!

fetchData
  .then((data) => {
    console.log(data); // Got the goods!
    return fetchMoreData(); // Next chapter!
  })
  .then((moreData) => {
    console.log(moreData); // More goodies!
  })
  .catch((error) => {
    console.error(error); // Oh no, plot twist!
  });
πŸ’‘
What to play around with this code? Check out this link!

Sometimes, you need multiple promises. Enter Promise.all – the Avengers of promises.

Promise.all([ironManPromise, captionAmericaPromise])
  .then(([ironManData, captainData]) => {
    console.log(ironManData, captainData); // Teaming up!
  })
  .catch((error) => {
    console.error(error); // Superhero down!
  });
πŸ’‘
What to play around with this code? Check out this link!

πŸ”œ Async/Await: The New Kid on the Block

And then there's the new kid, async/await. It’s like shorthand for working with promises. So fancy!

async function fetchData() {
  try {
    const result = await fetchCoolData();
    console.log(result); // Fancy data, here I come!
  } catch (error) {
    console.error(error); // Oops, something broke!
  }
}
πŸ’‘
What to play around with this code? Check out this link!
πŸ’‘
Want to know more about async/await? Checkout this page!

πŸ”§ Promise API: A Toolbox of Tricks

Promises come with a bunch of handy tools – Promise.resolve, Promise.reject, Promise.race, and Promise.finally. They’re like the Swiss Army knives of async.

βœ… Promise Resolve

Imagine you're ordering a package online, and the website uses promises to handle the delivery process. πŸ“¦ You get an instant confirmation that your package is on its way, and everything is 'All good!' πŸššπŸ’¨

In the follow example, deliveryPromise is like the promise from the delivery service, already resolved with the message 'Your package is on its way!'. The .then() block is where you excitedly check the message when the package arrives, and everything is indeed 'All good!' πŸ₯³. No need to worry about delivery issues! πŸš€

const deliveryPromise = Promise.resolve('Your package is on its way! πŸ“¦πŸŽ‰');

deliveryPromise.then((message) => {
  // This function is executed when the delivery promise is resolved
  console.log(message); // Output: Your package is on its way! πŸ“¦πŸŽ‰
}).catch((error) => {
  // This function is not executed in this case since the promise is resolved, not rejected
  console.error(error);
});
πŸ’‘
What to play around with this code? Check out this link!

πŸ™… Promise Reject

The same is true for Promise.reject. In the follow example, deliveryPromise is like the promise from the delivery service, already reject with the message 'Your package is on its way!'. The .catch() block is where sadly check the message when the, and everything is indeed 'All good!' πŸ₯³. No need to worry about delivery issues! πŸš€

const deliveryPromise = Promise.reject('Something is wrong with your package! 😒');

deliveryPromise.then((message) => {
  // This function is not executed when the delivery promise is resolved
  console.log(message);
}).catch((error) => {
  // This function is executed in this case since the promise is rejected, not resolved
  console.error(error); // Output: 'Something is wrong with your package! 😒'
});
πŸ’‘
What to play around with this code? Check out this link!

🐎 Promise Race

Let's imagine a scenario where you have two delivery services, and you want to use Promise.race to see which one delivers first.

In the following example, deliveryPromise1 and deliveryPromise2 represent two different delivery services. Promise.race is used to resolve with the message of the first delivery that arrives. Service 2 is faster, so the result is 'Delivery from Service 2!'. πŸš€πŸ“¦

const deliveryPromise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Delivery from Service 1! 🚚🏠');
  }, 2000); // Service 1 takes 2 seconds
});

const deliveryPromise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Delivery from Service 2! πŸ›΅πŸ ');
  }, 1500); // Service 2 takes 1.5 seconds
});

const fastestDeliveryPromise = Promise.race([deliveryPromise1, deliveryPromise2]);

fastestDeliveryPromise.then((message) => {
  // This function is executed when the fastest delivery promise is resolved
  console.log(message); // Output: Delivery from Service 2! πŸ›΅πŸ 
}).catch((error) => {
  // This function is not executed in this case since the promises are resolved, not rejected
  console.error(error);
});
πŸ’‘
What to play around with this code? Check out this link!

πŸ”š Promise Finally

The finally method is used with promises to specify a function that will be called regardless of whether the promise is resolved or rejected. It's commonly used for cleanup operations or actions that should be performed no matter what the outcome of the promise is.

In the following example, the finally block is used to log a message indicating that the delivery process is complete. This will be executed regardless of whether the delivery was successful or if there was an issue. 🚚🎊

function checkDeliveryStatus() {
  return 'successful';
}

const deliveryPromise = new Promise((resolve, reject) => {
  const deliveryStatus = checkDeliveryStatus();

  if (deliveryStatus === 'successful') {
    resolve('Your package is on its way! πŸ“¦πŸŽ‰');
  } else {
    reject('Oops! There was an issue with the delivery. 😟');
  }
});

deliveryPromise.then((message) => {
  // This function is executed when the delivery promise is resolved
  console.log(message); // Output: Your package is on its way! πŸ“¦πŸŽ‰
}).catch((error) => {
  // This function is executed when the delivery promise is rejected
  console.error(error); // Output: Oops! There was an issue with the delivery. 😟
}).finally(() => {
  // This function will be executed no matter whether the promise is resolved or rejected
  console.log('Finally, the delivery process is complete! πŸŽ‰');
});
πŸ’‘
What to play around with this code? Check out this link!

πŸ’­ Final thoughts

JavaScript promises are like superheroes for handling asynchronous tasks, simplifying code and enhancing readability. They operate in three states – pending, fulfilled (success), or rejected (issues). Using promises involves wrapping async tasks, resolving for success, and rejecting for issues, akin to ordering pizza online. Success is celebrated with then, and issues are handled with catch. Chaining promises creates a sequential story, but if one fails, the next won't be called. For teamwork, there's Promise.all – the Avengers of promises. The new kid on the block, async/await, offers a sleek shorthand for working with promises. The toolbox includes Promise.resolve, Promise.reject, Promise.race, and Promise.finally – the Swiss Army knives of async. Whether tracking a package, handling errors, or racing deliveries, promises are the MVPs in the async world, making JavaScript adventures more readable and less chaotic. πŸš€

References

Go deep on promises πŸ‘‡

Did you find this article valuable?

Support BitTonic // Ricardo by becoming a sponsor. Any amount is appreciated!

Β