.then(what?!)

I’ll get it eventually: An exploration of promises

Alejandro Belgrave
May 2 · 7 min read
a finger promise

Last week I began learning deeply about the inner workings of the Javascript runtime. Starting at creating the global executable scope, the multiple passes of definition and execution at runtime, all the way to the runtime going through the code and executing via the call stack, things started to make sense. My understanding of how things worked, however, got fuzzy once AJAX requests jumped into the loop.

I had a lot of questions that made me more and more confused. The kind of confusion that makes you question what you know while trying to discover what you don’t know. The source of the confusion centered around promises and the event loop. (I wouldn’t understand how I got here, however, until much further down the rabbit hole). My questions, like promises, only returned more questions that may provide answers.

The Run Down

This post will be about how I refactored my original questions when first diving into Javascript asynchronous calls; documenting my understanding of Promises and how they work when chaining. I will also be highlighting the things I thought I understood but didn’t, questions that arose because of further research, as well as the new information that filled in the pieces. So what was my original question?


The Question(s) that Began it All

After the initial exposure to the hood side of AJAX requests, a couple of questions arose:

Is the then promise the same as the original return promise?

How does the event queue know where to return the information once its returns form the event loop?

My confusion about then() first occurred when I was using fetch() to make a network request to receive some data. So that’s where I began. What exactly does fetch()do?

fetch()

fetch()is a modern way of making network requests provided to us by the browser. Its syntax allows for simpler means for formatting requests necessary to make successful server calls. My first search led me to fetch()’s MDN page. Below is what they had to say about it, I will also be referring to their code sample for the rest of this article.

a screenshot of the fetch MDN web doc page

This fetch call makes a GET request to receive all of the movies from the backend server’s database. What is important to me, however, is the last sentence of the first paragraph. fetch()returns a promise not the actual result. This means that fetch()is a function that makes an asynchronous call. Without delving too deeply into fetch() two more questions arose: why do we need to make an asynchronous call in the first place? How do promises work?

(Aside) Brief History of AJAX

Because Javascript is a single threaded language, by design it cannot do two things at once. At runtime it will run one line at a time and run one function to completion and then move on to the next one. This is how the call stack works, pushing functions on to the stack and only popping them off when they return a value. Since our JavaScript programs will run calls that make network requests that can take an unknown amount of time, these call have the potential to noticeably block our code. In a time where consumers expect blazing speeds, a solution was created to allow JavaScript to make asynchronous requests. Thus, allowing basic user functions (like scrolling and clicking) while potentially long calls are being made.

So what fetch() (and other asynchronous functions) do is immediately return a promise once it is next on the call stack so that the request doesn’t block the code).

But that then made me ask, what is a promise? How does it work?

Promises

My initial understanding of a promise was as follows: a promise is this object made for asynchronous requests that will eventually give us some data or let us know if it couldn’t. To check if I was on base, I looked at a trusted source: the MDN docs. It says:

A Promise is an object representing the eventual completion or failure of an asynchronous operation.

Upon further investigation, I learned that the Promises API helped solve the nesting and error handling problems brought by the traditional method of making asynchronous calls.

The idea behind the inclusion of Promises can be summed up by this StackOverflow answer:

a screenshot describing the high level concept of promises

The Promises API also provide certain garuntees according to the MDN web docs:

Callbacks will never be called before the completion of the current run of the JavaScript event loop.

Callbacks added with then() even after the success or failure of the asynchronous operation, will be called, as above.

Multiple callbacks may be added by calling then() several times. Each callback is executed one after another, in the order in which they were inserted.

So my knowledge expanded. To recap, a Promise is an object that will eventually hold a value. We can return this object immediately so that our code is not blocked. A promise returns a promise and you can chain promises with their then() function. This enables us to only run a callback function when we know the previous call has completed.

But there it is again. Reading through the garuntees re-triggered my question: how does then() know when to run? How does step 3 in that StackOverflow answer works?

then()

Scrolling down in the Promise web doc, I foundthen(). What I read next challenged what I thought I knew. It said:

Promise.prototype.then()

Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler, or to its original settled value if the promise was not handled (i.e. if the relevant handler onFulfilled or onRejected is not a function).

Firstly, then() is a method of the Promise object. I thought then() was a global function available to us by the window like fetch() or alert().

So when we write then(fulfill, reject) we are in fact adding the callback functions references onto the Promise that was returned on the previous call. Once that promise is settled, it then uses the resolved value as the argument to the callback function we just appended and runs it (returning the value wrapped in a Promise).

Great so that’s how then() works. Does that answer my question? No, but understanding the nature of then() moved me closer to a better question. then() is triggered after its Promise resolves. How does it know to do that?

Understanding My Confusion

Through endless googling, I discovered that my exploration was not comprehensive, and my confusion lies in what I am not reading. The JavaScript side of that initial fetch() call and promises make a lot more sense to me. What I do not know is what is happening when we leave JavaScript. Asynchronous functions’ work is done outside of JavaScript. When the call stack pops off an asynchronous function and returns the promise, what does it send to the web APIs? From there what is sent back to the event queue, alongside the information that will become the returned promise’s value? And from the event queue, how does the specific promise know when to change from pending to resolved or rejected to then call the then() method?


Ultimate Question

What is passed through the event loop? How does JS/Event Loop know to call then() on the promise? How does it know to resolve?

Wrapping Things Up

The Process

Even though I am still in the midst of a confused state, I feel optimistic in my search. My optimism comes from the process. Even though asking a question prompts more questions, like promises, some of these questions may yield answers. Little by little, I am learning more about promises and the JavaScript runtime. I am also learning how find answers; with every bit of information learned, I am better able to articulate what I know and what I don’t know, providing more informed and specific queries. And in terms of promoting growth, it is important to know what you know and what you don’t know to achieve greater understanding (of the things you don’t know).

Slightly Irrelevant Take Aways

  • I learned that there is no standard, real way to view the browser’s event loop.

Resources

MDN Then Doc

Stack Overflow Scope Question

MDN JavaScript Event Loop

Our Code World Article

How JavaScript Promises Work

MDN Promises Web Doc

Stack Overflow Event Loop Question

Promises In Wicked Detail

ECMA Promise Constructor

Alejandro Belgrave

Written by

Technologist specializing in Software Engineering. Diving deeper into how things work and why. Just sharing my questions and discoveries in real time.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade