I’ll get it eventually: An exploration of promises
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
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()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.
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
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?
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:
The Promises API also provide certain garuntees according to the MDN web docs:
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?
Scrolling down in the
Promise web doc, I found
then(). What I read next challenged what I thought I knew. It said:
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).
then() is a method of the Promise object. I thought
then() was a global function available to us by the window like
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
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
Slightly Irrelevant Take Aways
- I learned that there is no standard, real way to view the browser’s event loop.
- I am okay with not knowing.
- It gives me comfort that this question is answerable, as the feature has been implemented. Meaning someone, somewhere, has thought it through. It gives me hope that some day I can answer this question for myself.