Skip to main content

Command Palette

Search for a command to run...

JavaScript Promises Explained with Geopolitics analogy

Updated
5 min readView as Markdown

If you are reading or watching the International news, you have heared about the trade deals, tariffs, oil agreements, and economic partnerships between countries. It sounds complex, but internally, it’s just If you ready to do X by the time Y, I’ll do Z for you in return.”

JavaScript Promises work in that much similar way, they are agreements about something that will complete in near future. In place of countries, we have block of code. place of tariffs, we have promises and timers.

In this blog, we’ll understand JavaScript Promises as trade deals between fictional countries name like CodeLand and Scriptistan. avoid real conflicts, only goal is to master JS promises by these type of simple stories.

What is Promise ?

A Promise in JavaScript is a object that will represents the event completion or failure of async operation and its result.

In our analogy, we can say a Promise is like a trade deal agreement between two countries:

CodeLand which is your JavaScript code

Scriptistan is where some external resource exists like API or database

They decided to make a trade deal and they start with negotiations that “If you buy oil from me from next month, I will reduce tariffs on your products” so until that actually happens in the real-world, this is just a promise.

A Promise can be concludes at one out of three states:

  • Pending: Negotiations are still going on table and require some refinement in that. No final decision yet. In JS Pending stands for async operation which is still running.

  • Fulfilled: Deal is signed and implemented by both country with a good satisfaction. Promise succeed. In JS Fulfilled stands for resolve(()=>{ }) which is called in that case

  • Rejected: Negotiations failed and No deal with some reason of unsatisfaction. In JS Rejected reject(()=>{ }) which is called in that case.

example


let tariff = 50

let check = new Promise((resolve, reject) => { 

 if (tariff < 18) {
  resolve("trade deal is successful")
}{
 else reject("trade deal is unsuccessful")
 }
)}

 check
.then((data) => console.log(data))   //  success 
.catch((err) => console.error(err))  // failure

Consuming Promises: Then, Catch, Finally

Once CodeLand and Scriptistan are negotiating, other parts of the world want to know that is deal is happening or not and what is the current status of deal:

What to do in deal succeeds. In JS .then() for success.​ What to do in the deal fails. In JS .catch() for failure.​ What to do in any case at end. In JS .finally() for clean, if it is success or fail.​

Example:

Promise.resolve("Deal signed")
.then((result) => console.log(result)) // success  
.catch((error) => console.error(error)) // failure
.finally(() => console.log("adjustment")); // always runs

Promise.all()

Promise.all() waits for all Promises to fulfill and then returns an array of their results. If any one Promise is rejected, the entire Promise.all is rejected.

Promise.all(
[ Promise.resolve("Deal with Country A done"),
 Promise.resolve("Deal with Country B done"),
Promise.reject("Deal with Country C failed") 
])
.then((results) => console.log(results))  // success 
.catch((error) => console.error(error))   // fail

according to Analogy three different countries are forming a trade deal of zero tariffs. The deal only stays, if all three representative will approve. If even one parliament says “No”, the whole deal will cancel.

So Promise.all is great when we need every deal to succeed or to check that if anyone have cancel the plan

Promise.allSettled()

Promise.allSettled() waits for all Promises to settle either promise is fulfilled or rejected. it basically returns an array of objects describing each outcome by returning status and reason

Promise.allSettled(
[ Promise.resolve("Deal with A done"), 
  Promise.reject("Deal with B failed"),
  Promise.resolve("Deal with C done") ]) 
.then((results) => console.log(results))

according to the analogy. The foreign ministry wants a complete report on all negotiations. They don’t stop when any one country says NO to do trade deal. they needed report about trade deal.

They wait until every negotiation ends, then publish a file like:

[ Country A: fulfilled, Country B: rejected, Country C: fulfilled ]

Use allSettled when want to know about what really happened in every case, why is all not agree who is disagree with deal

Promise.race():

Promise.race() resolves or rejects as soon as first Promise settles either it fulfills or rejects.

Promise.race(
[ new Promise((resolve) => 
setTimeout(() => resolve("Deal with A signed"), 1000) ), 

new Promise((resolve) => 
setTimeout(() => resolve("Deal with B signed"), 500) ) 
])
.then((result) => console.log(result))

According to the analogy CodeLand is talking to multiple countries at once for making a tradedeal with fast pace. any country signs a good enough trade deal first gets the markets first to sell or buy product. The others may still be negotiating in background, but for now the deal happens to first one.

Use race when who ever responds first with a result is only one who get's opportunity

Promise.any()

Promise.any() resolves with first fulfilled Promise and ignores rejections unless all reject, in which case it throws an Error

Promise.any(
[ Promise.reject("Deal with A failed"),
 Promise.resolve("Deal with B succeeded"),
 Promise.resolve("Deal with C succeeded") ])
.then((result) => console.log(result))  // success
.catch((error) => console.error(error)) // error

according to the Analogy, CodeLand is looking for any one country willing to buy its new tech products. It doesn’t care who says “Yes” first; it just needs one partner. If all countries refuse, then it’s a total failure.

Difference from race:

  • race → reacts to first settled Promise whether it is success or failure.

  • any → reacts to first success, ignoring earlier failures.