Promises (udemy)

What is a Promise?

A promise is an object that keeps track whether an Asynchronous event happened or already. Then how it gets handled in the future.

Promise can have different states:
pending – when the final value is not available yet. This is the only state that may transition to one of the other two states.

resolved – Fulfills the associated promise with the specified value, or propagates the state of an existing promise. If the associated promise has already been resolved, either to a value, a rejection, or another promise, this method does nothing.

fufilled – when and if the final value becomes available. A fulfillment value becomes permanently associated with the promise. This may be any value, including undefined.

rejected – if an error prevented the final value from being determined. A rejection reason becomes permanently associated with the promise. This may be any value, including undefined, though it is generally an Error object, like in exception handling.

We make an instance of Promise by using ‘new’. Once an instance is made, we need to insert an executor function. This executor function will be processed by the Promise object asynchronously and it will pass two callback functions to you: resolve, and reject.

Once the process is done inside of your executor function, you execute the callbacks to let the Promise object know that you have received the data you wanted.

The Executor takes in two callback functions: resolve and reject.
It is used to inform the promise of whether the event is handling whether it is successful or not.

If success, call resolve.
If not successful, call reject.

You can wrap a function outside of the promise. But make sure that you call a then for the returned Promise object.

Look at runPromise(). It executes innerPromise(), which returns a new Promise object. We then wrap a then() to it and thus, it will wait for the data to return.

Ultimately, we want to give the result to outside most function. When we executed runPromise(), we get the Promise object from innerPromise(). We must take care of this returned Promise object, so we chain a then() in runPromise() and we’ll get the data.

Therefore, it’s all about chaining .then() to the returned Promise object.


-- runPromise --
-- innerPromise --
-- start the executor --

2 seconds later...

data fetched from server!
innerPromise()'s then - data returned
runPromise()'s then - data returned
lots and lots of important data

Using reject

Now, let’s replace resolve with reject.

When you run the code, after two seconds, we get an error in the console:


Uncaught (in promise)

This is because we have nothing to catch those errors. Let’s chain a catch:


-- runPromise --
index.html:29 -- innerPromise --
index.html:31 -- start the executor --
index.html:33 data fetched from server!
index.html:51 HTTP 503 Error Code - Server down

Chaining Promises

We first have a fetchOrder function that returns a Promise object. This Promise object simulates getting an order via GET operation on a web server:

We then create a sendOrder function. It simulates sending data to another server using PUT/POST. It’s supposed to put the order into that server.

Finally, let’s chain these Promises together. We do so by doing the standard procedure of getting the first Promise and then chain a then() to it. The trick is to return another Promise object here so that we can continue chaining then to it.

Note that we can also return primitive values here, which JS will automatically wrap a Promise object around it and return it. Thus enabling us to keep chaining away. However, to be precise and clear, you should return functions that return Promise objects.