In this guide, I'm going to walk through exactly how we can work with promises in JavaScript.
However, before we can talk about this, I want to give more of a explanation on what promises are.
And thankfully, because of the way promises were created and how it's named, it's pretty easy and
straightforward to compare it to a real world scenario, and that is of a promise in real life.
So imagine that I come to you and I say that I am going to mow your lawn.
Now, that is a promise that I've made to you.
Now, there's a couple things that could happen when I say I'm going to mow your lawn.
There are three scenarios.
The first one is that I go outside and I start mowing.
That's scenario one.
And in JavaScript, we would say that this is the pending status.
This is kind of like what happens when we make an API request and it creates a promise or it starts
a promise and we're waiting to see what is going to happen.
Now, taking the mowing example further, if I complete the mowing process, I'm going to come back
and I'm going to say I'm done.
And in that case, I was successful and I fulfilled my promise.
In JavaScript, we would say that this is been resolved.
The key word here is resolve.
And that means that the promise proved to be true, came back successful, and everything went as planned.
However, what happens if I run away and I just start running down the street and I do not mow your
lawn?
That means that I did not complete the mowing process successfully.
Now there is a special term for this, and this is going to be called the reject status.
And what this would be akin to is sending out an API request and having an error message come back,
either the server was down or any number of various errors.
And if you want to take this a step further in the analogy, it isn't that always the case that maybe
I lied about mowing the lawn.
That also could be that I went outside to mow the lawn and there was no gas in the lawn mower or the
lawn mower was broken or something like that.
All kinds of different reasons why I may not be able to hold true to my promise.
Just like there's all kinds of reasons why a program may not be able to fulfill the promise successfully.
However, what I really want to kind of impart to you is the three stages of a promise.
One is when it's pending and the next is when it's successful, which is what we'll call resolved.
And the last one is when it's rejected.
So those are the three things.
And I'm going to keep this comment here in the source code just so you have access to it.
So you have kind of that analogy in your mind.
Because when I was learning about promises, I heard kind of a similar analogy, and that was one of
the things that really made it clear to me.
Now, in order to use promises in the version of JavaScript we're using, we need to put something at
the top of the file.
And actually I'm going to put the very top of the file just so it's clear that's being used.
And this is going to be called use Strict.
Now what this means is that we're going to be using the strict definition or the strict process in JavaScript.
If you have any experience with JavaScript, then you probably have heard about the strict process or
the strict syntax, and that's what we're doing here.
It doesn't really change how we're going to be building the program.
It's simply something that is required for the JavaScript compiler for this ES6 version.
As a side note, if you're keeping your compiler options in your TS config file, if you go back to
some of your previous classes or your previous coursework, such as the work that we did with classes
or some of those things, or even anyone that has the let statement included, that is going to now
no longer work without putting use strict at the top.
So just as a side note, if you go and try to rerun any of those programs and you get an error, if
you're using the new compiler options, you just have to put that at the top and you'll be good to go.
So now let's move on forward and let's talk about how we can create a promise.
So usually the way promises are created, this is a traditional way, is we're going to create an anonymous
function.
So we're going to create a function expression.
And for our example in this guide, I'm going to mimic the process of uploading a image to a either
an image or anything like that, uploading that to a server.
And we're going to have a number of processes that we're going to force to happen in a specific order.
So I'm going to call this function perform upload, and it's we're going to set it equal to an anonymous
function.
And this function is going to take one parameter.
The parameter is going to be image status, and that's going to be of type string.
Now this is going to return a promise.
So this promise is going to be returned.
And also we're going to pass a key value pair inside of this promise.
So we're going to inside of it put put angle brackets and inside of that place image status and set
that equal to string.
So what that's going to what we're essentially saying is this program is going to return a promise,
and this promise is going to contain a status.
And that is what is going to be returned when perform upload is called.
Now, the next thing we're going to do is we need to actually return it.
So we're going to say return new promise.
And inside of the promise, we're going to pass a couple things.
First thing we're going to pass is going back to our lawnmower example.
We need to pass in what will happen when the item is successful.
So we need to pass in a resolve argument.
And what this is saying is that when the item is successful, we're going to be resolving this process.
So this is what's going to happen.
When that occurs.
And what I want to do and notice how I'm using our fat arrow syntax for the function here.
I'm going to console log out something and we're going to use string interpolation.
So use the Backticks and I'm going to say status and I'm going to set the status equal to whatever the
value of image status is.
And right after the curly brackets, I'm going to do another backtick and end that line of code.
And because I want to kind of mimic a real world process, I'm going to put a set timeout function in
here and with set timeout, this one, if you remember back to when we did this in our callback, we're
going to pass, set, timeout a another function and we're going to use another fat arrow in order to
do it.
And inside of the fat arrow, we're going to place exactly what we want.
This to do.
So here inside of the set timeout, this is where we're going to pass resolve.
Now, if you notice, resolve is going to work like a function here.
So resolve, even though you notice that resolve is an argument, we're going to pass this argument
a function and we need to pass in the value that we want to return.
So what really is happening here is that when a successful promise has occurred so there's no issues
and everything comes back, what we're saying is that we're going to return the image status.
And remember, we're returning this as a key value pair.
And if part of this still seems a little bit confusing, do not worry, we're going to go through and
kind of go line by line on exactly what's happening.
To review here and I want to pause this for one second.
So I'm going to put in a 1000 millisecond call here.
And that is it, except for adding a semicolon to the end of this.
And that is a promise.
And so it's going to make a little bit more sense.
Everything that's going on here when we actually call the promise.
So the first thing I'm going to do is create some variables.
So I'm going to say var upload.
Var compress, and then var transfer.
And now that we have all this in place, now we can actually call our promise.
So our promise is called perform upload.
And in order to start this, we're going to pass in whatever status we want to do.
So in this case, I'm going to say uploading.
And then we're going to process the very special keyword then.
Now, if you've never worked with promises before, then you may have never heard of the word then in
programming.
But I like it because it's very nice and sequential and it's a great way of organizing code because
to me it almost reads like English.
So the way we're going to do this is start a new line.
You could put all this on the same line.
However, that would be very difficult to read.
So Standard convention is to put it on a new line.
So we're going to call the function then and inside of then.
Then takes an argument and it takes in a callback.
So we're going to say we're going to pass in the response.
And then inside of that, we're going to use our fat arrow and we're going to pass in the response and
set upload, which is the variable that we created right here.
And we're going to set upload equal to the response.
And then I want to return a value in this function and I'm going to say perform, upload.
So we're calling the Promise again, but now we're going to pass in the value of compressing.
Which is another image status.
And let me just copy and paste this code because we're going to use this for each one of the statuses.
So we're going to do that one and then we're going to do one more.
But this last one is the final one, so this one's going to be slightly different.
So this one is going to say transferring.
And we're not going to set upload equal to it.
We're going to set compress equal to it.
And then the last one is going to be transfer.
And this one is going to say image upload completed.
The very end.
Add a semicolon and this should all work.
So let me come over here to the terminal.
Run the code.
Everything looks like it worked there.
This is number 29 promises.
In case you're following along with the source code, you can see it uploads, compresses, transfers,
and the image upload process has worked.
Okay, so that worked.
However, if you've never worked with promises before, this probably didn't make a lot of sense.
And so I want to circle back and kind of go through each element and analyze what it's doing.
So in review here, this is our actual promise.
So our promise is called perform upload, and our promise is an anonymous function.
It takes an image status, which is a string value, and then it is going to expect that we're going
to return a promise because we said that we're going to expect to return this.
That's why the first thing we do is we say return a new promise.
So this means that when this function is called, it's not going to take in, say, A, it's not going
to come back with a console log statement by itself or anything like that.
It's actually going to return an entire promise object.
And that's what we're doing right here.
When we say return new promise, now a promise itself, it takes in it because at the end of the day,
it's a class.
But whenever you create a new promise, it expects a callback.
So if you remember our guide on callbacks, that's what this is right here.
So we're passing in a function to promise and we're saying when this resolves, which if you remember,
that means when it's successful, I want you to do everything inside of here.
So that's all it's saying.
It's saying that when this occurs, then I want you to do all of this cool stuff.
I want you to console, log out this value.
I want you to say the image status.
And remember, we're getting image status because every time we call perform upload right here, we're
passing in a value.
You can even come down here and see it.
First time we call it, we're passing in uploading, then we call it we're passing in compressing.
Next time we call it, we're transferring.
And last we're doing it when it's complete.
So it takes in this value and then it passes it to the status.
And then from there we are setting a timeout and this one's just to give us a pause.
I mean, if we got rid of all this, it would run through, but it would all look like it ran through
instantly.
What this is doing is it's giving us a one second pause and it is going to be running the resolve code.
So it's going to be running.
It's saying that this was successful and it's passing in the image status and this is what would be
returned.
We're not actually working on the values that are returned.
So it's not that big of a deal.
But I wanted to show how you would usually pass in the resolve status because in as far as what we can
see, this is all the code we're actually seeing.
However, in a real life callback or in a real life promise, you'd want to return a real value.
So say that this image uploader was connected to like an S3 CDN or API where you're passing up image
uploads and you want to be able to have them processed.
This would be the value you'd actually get, which is the resolve status, and then you could include
that in the rest of your code.
So this would return the value and then everything.
So that's the entire promise.
Now moving down, we created these variables just so we could have variables we could assign things
to, and then we could create stages for the promise.
So if we imagine that our upload process included the uploading, compressing the file and then transferring
it to a different server, then that's these, that's what these three stages represent.
So the first thing we're doing is we're calling the promise.
We're passing in uploading.
When this is completed, then it hits this, then method.
So it hits then.
And if you're wondering what then takes in, it takes in a callback and it takes specifically, it takes
in the response.
So if you want to imagine what this would look like in a real life application, perform upload would
be like the user clicking the upload button on the website that sends up uploading and it connects to
the server from then the system.
Was going to say, okay, well, what do you want me to do next?
That's what the then keyword really represents.
And so we're saying, I want you to start the upload.
When this is complete, then the server is going to send back a response message.
That's what Rez is short for.
It's short for response and we could change each one of these to be a response.
I just did Rez because that's kind of the standard convention, but what it means is this is what the
server is responding back with.
Now we get that because this promise is going to return the value.
You remember when I talked about the resolve item and what it returns, that's what it's doing is it's
passing this value and then we're setting upload equal to response and then we return and we kind of
continue the chain.
So the next thing is we're performing an upload, we're taking in the value of compressing and we keep
on moving down all the way until it's complete.
Each one of these is simply a stage.
It uses the then keyword so that it can make the whole process sequential logically, and then that
in turn takes in whatever the response was on the previous process.
So here it takes in the response of uploading here, it takes in the response from compressing and here
it takes in the transferring response.
And that is how you can work with promises in JavaScript.