The Web Developer Bootcamp 2024
Colt Steele
Colt Steele
JavaScript Promises are a means of sending and receiving data to an "external" source, such as a web API. The "promise" is that Js will send a request for the data, and that a response for either a successful retrieval of the data, or a failure in the retrieval, for what ever reason, is received. For example. Say you have a web app that has the current weather displayed on the page. You would send a request to the weather source API to retrieve that data. The coding in the "Promise" would ensure that you would get a response, whether you received the data or not.
Here is a technical definition:
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.
A Promise is in one of these states:
The eventual state of a pending promise can either be fulfilled with a value or rejected with a reason (error). When either of these options occur, the associated handlers queued up by a promise's then method are called. If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached.
*A promise is said to be settled if it is either fulfilled or rejected, but not pending. More info can be found here:
Normally when using Ajax, or other similar technologies, we don't write too many Promises ourselves. We just normally write the code that will interact within the promise. But if we did write a Promise, this is commonly how it would be written:
So we've created a function with a Fake Request, which will send a request to a dummy link (url). Within this function, we have created a new Promise, which will return the results of this Promise.
Within the Promise itself, we have set up a Random Number Generator, which will return a random number between 0 and 0.9. We then set up an if loop. if the random number is less than 0.7, the Promise will return a resolve(), otherwise it will return a reject().
Now within the Promise itself:
And now to call the fakeRequest function:
So if the fakeRequest function returns a resolve(), then the console will log "Request Complete : Fake Data was returned." But if the fakeRequest function returns a reject(), the console then logs "Oh No!! Error Retrieving the Fake Data!!".
We need to understand that this is just a very basic example that is simply showing the "concept" of Promises. The results of a resolve(), or a reject() are dependant on the random number generated.
But in reality, these results would be determined by the outcome of the data request, and that outcome would be set by the resolution, or rejection of the Promise. You would then write the appropriate code to deal with both scenarios, the resolution, and the rejection, so that your program could deal with both outcomes.
Async & Await are a "newer" means of working with Promises.
Async & Await in JavaScript are used to simplify handling asynchronous operations using promises. By enabling asynchronous code to appear synchronous, they enhance code readability and make it easier to manage complex asynchronous flows.
More info can be found here:
Here is a simple example of using async:
So we've created a async function to parse a login attempt for valid information.
And next we would need to call this function:
So if we leave either the username or password fields blank, then the console logs the message "ERROR!, Credentials Incomplete!"
If we enter an invalid password, the console logs "ERROR!, Invalid Password"
And finally, if we enter a correct username and password, then the console logs "Welcome, you have successfully Logged In."
We now know that placing “async” before a function, means one simple thing. This is an async function, and an async function always returns a promise. In other words, the keyword async before a function, always makes the function return a promise
The await expression pauses the execution of its surrounding async functions, until that promise is settled (that is, fulfilled or rejected). When execution resumes, the value of the await expression becomes that of the fulfilled promise.
An await is only valid inside async functions and modules. It wil pause the execution of the async function, and waits for a promise to resolve, before it continues.
Let's start with this example. We're going to add a <div> with a width of 400px and a height of 35px (as defined in a css stylesheet). We're going to give the <div> and id="colorChange", so we can reference it within our JavaScript:
Next, we're going to write a function that will create a new Promise that will change the background color of our div, every 1.5 seconds (1500ms):
Next we need to create our async function which will pass in all of the colors for the background color changes. And inside this function will be several calls of the function delayedColorChange(), which if we look at the function, we see that after 1.5 seconds, it changes our <div>'s background-color. But wait Houston... we have a problem.
If we call our async function, and pass in our first two delayedColorChange() functions, like so:
What do you think happens? Do we see a Red background, and then 1.5 seconds later a orange background?
Well, actually we don't.
Because we've told our colorChange function to wait 1500ms (1.5 seconds), but when we call this function a second time for the second color, it actually changes the color before the 1.5 seconds the timeout calls for. So it has changed the background color twice, before the timeout has finished running. So instead of getting Red to Orange, we just see the Orange.
And this is where we find the use for our await expression.
Remember that we can only call await inside of an async function. And an async function always returns a promise. So when we preface our colorChange function with await, it forces the Promise it is working on, to wait until it has finished, before moving on to the next Promise.
So our async function would be:
And finally, all that's left to do is to actually call the rainbow() async function:
And here is our final result. Our <div> with changing background color.
So as we can see, the await expression has paused the execution of its surrounding async functions, until that promise is settled (that is, fulfilled or rejected). And in our example, the end result is that every color change requires a 1.5 second delay before moving on to the next one.