← back to blog

Last time you'll go through promises......I promise.

March 1, 2026 · 4 min read

Before we begin there are a few things to know about javascript:

  • JavaScript is single-threaded ----> One call stack -----> One thing executes at a time.

  • But in the real world, the apps/ websites we use talk to servers, they read files, server performs operations on data ----> These things take time ---->If JavaScript blocked while waiting, your UI would freeze.

  • Promises to come to our rescue.

A Promise is a value that represents the result of some time taking operation (async) — now, later, or never.

WHAT?

Promise = a container for a future result.

It can be in only have one of these 3 states:

  • pending → still waiting

  • fulfilled → succeeded (even of server responds with an error it is a fulfilled promise)

  • rejected → failed (Reject runs only when something breaks (like no internet, server failure, or DNS issue))

After it becomes fulfilled or rejected, it’s done and final ----> It cannot switch its state again.

Flashback

Before Promises, async (time-taking) code stacked inside itself like this:

getData(function(data) {
  cleanData(function(cleaned) {
    saveData(function() {
      console.log("Finished");
    });
  });
});

Each step waits for the previous one, but the nesting keeps growing. Hard to read. Hard to manage errors. Try doing this for 45000 times you'll understand what I mean.

With Promises, the same code becomes flat and linear: most imp ----> READBLE

getData()
  .then(cleanData)
  .then(saveData)
  .then(() => console.log("Finished"))
  .catch(error => console.log("Something went wrong"));

Now how do we create a promise?

const myPromise = new Promise(function(resolve, reject) {
     let ok = true;

     if (ok) { resolve("Done");} 
        else {reject("Error");}
});
  • resolve("Done") → Promise becomes fulfilled , reject("Error") → Promise becomes rejected
    Only resolve or reject can settle the promise.

Using a Promise:

herPromise
  .then(function(result) {
    console.log(result);
  })
  .catch(function(error) {
    console.log(error);
  });
  • .then() runs if it was fulfilled

  • .catch() runs if it was rejected

Both .then() and .catch() return a new Promise. That’s why we can keep chaining them.

HEART of promises

Every .then() gives you a new Promise.

fetch("/her-api")
  .then(res => res.json()) 
  .then(data => show(data))
  .catch(err => showError(err));

NOW...........read carefully:

Each step waits for the previous one.

Inside .then():

  • If you return a normal value → it goes to the next .then()

  • If you return a Promise → it waits for that Promise

  • If you throw an error → it skips everything and goes to .catch()

NOTE: Errors automatically move down the chain until they find a .catch().

something about fetch()

fetch() only rejects ----> when the network fails (no internet, DNS issue, blocked request).

It does not reject for 404 or 500 errors. So this still counts as “success” to fetch:

WHAT PROMISES DO NOT DO:

Promises are not workers. They don’t do the work.

  • They do not create threads.

  • They do not make JavaScript parallel.

  • They do not run in background magically.

  • They do not block execution.

They only manage the timing and flow of time taking operations

The real async work is done by:

  • Browser APIs (like fetch, timers)

  • Node APIs (like file system, network)

  • The event loop (the system that decides what runs next)

A Promise is just a coordination tool. It says: “When this task finishes, do this then do this, then do this......”

I have created a visual playground for you to understand go and play it here:

https://chaipromise.netlify.app/.

Thanks for reading.

Last time you'll go through promises......I promise. — devzshrc.