Promise (js)

http://javascript.info/promise-basics
https://scotch.io/tutorials/javascript-promises-for-dummies
https://www.toptal.com/javascript/asynchronous-javascript-async-await-tutorial
https://stackoverflow.com/questions/39988890/do-javascript-promises-block-the-stack

Why do we need promises?

Say you have a url, when given two numbers, will return you the sum.
You give the url two numbers in its parameter, and issue a remote call to get the result.
Naturally, you need to wait for the result.

Sometimes, its slow in response, etc. You don’t want your entire process to be blocked while waiting for the result.

Calling APIs, downloading files, reading files are among some of the usual async operations that you’ll perform.

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

So this means once your Promise starts running (whether executing a timer or downloading from the internet) execution will continue on down the code. Once your Promise finishes (resolve or reject), then execution returns to the callback that you give to your Promise.

In this tutorial, we use setTimeout to simulate this server request response time.

The problem happens when we want to do callbacks in succession

say we want to add 1, 2, then get the result, and add 3. The get that
result and add 4.

If the calculation functionality is on a server, and we do this through this via callbacks, it would look like this:


result
info: querying url http://www.add.com
result1: 6
info: querying url http://www.add.com
result2: 9
info: querying url http://www.add.com
result3: 17

The syntax is less user friendly. In a nicer term, It looks like a pyramid, but people usually refer this as “callback hell”, because the callback nested into another callback. Imagine you have 10 callbacks, your code will nested 10 times!

Solution – Promise

Promises were the next logical step in escaping callback hell. This method did not remove the use of callbacks, but it made the chaining of functions straightforward and simplified the code, making it much easier to read.

Using promises in our previous example would make it simple.

First, we declare a function addAsync with two numbers to add.

We create a Promise object. Within our new created Promise object, we have a callback function parameter. We provide code that we want to execute within this callback. The callback function itself, has two parameters: resolve, and reject. Once the code has been executed and result is received, it will call resolve/reject in our code. This is so that a ‘then’ can be chained later on.

How is it a then() can be chained later on? The Promise object is returned from our addAsync function, for others to use. In other words, when they execute this addAsync, they will be returned the Promise object.

The reason why we want to return the promise object is so that others can call then on it. Calling then on a Promise object means that you’ll get notified when a resolve or reject is called within the Promise. The first parameter callback of our then() will be triggered if its a resolve. 2nd parameter callback of our then() will be triggered if it’s a reject.

The then function simply waits for the resolve or reject to happen.
If its a resolve, the first callback parameter of the then will be executed. If reject, the 2nd callback parameter will be executed.

Within setup of a Promise instance, we do a setTimeout to simulate a remote request that takes 2 seconds just like our previous example. Notice
that we don’t deal with custom callbacks. We now use resolve and then for the results.

Promise object’s resolve will trigger then()

Further Chaining…

ref – https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

Once a Promise is fulfilled or rejected, the respective handler function (onFulfilled or onRejected parameters of then() ) will be called asynchronously (scheduled in the current thread loop). The behavior of the handler function follows a specific set of rules.

If a handler function:

returns a value, the promise returned by then gets resolved with the returned value as its value

// much later…

output of aPromise is:

Promise {: 3}
__proto__: Promise
[[PromiseStatus]]: “resolved”
[[PromiseValue]]: 3

doesn’t return anything

the promise returned by then gets resolved with an undefined value

output of aPromise is:

Promise {: undefined}
__proto__: Promise
[[PromiseStatus]]: “resolved”
[[PromiseValue]]: undefined

throws an error

So if we only call the reject, it’ll only hit the reject handler like so:

output: REJECTED : Booo…less than 8.

Note that if you DO NOT HAVE a reject handler, the reject will automatically be taken care of in the catch handler.

Normally, the catch handler catches any thing throw in the Promise object.


output:

REJECTED : Ooopssiiie

There is a situation where where you have an async operation inside of your Promise object. As a result, you throw 1 second later. It won’t catch because the Promise object has already been executed.

The only thing that works is reject, which naturally gets caught, given there is no reject handler.

catch is not like then(), where then() waits for the resolve/reject. Catch DOES NOT WAIT for the throw

The idea here is that you use resolve/reject in your Promise to take care of any async operations so that the then() gets triggered when the async operation is done. Then, you go on with your throw/catches.

Never use async callbacks in your Promise object. Use resolve/reject first.

This is basically why you should not put async callbacks inside of promises.

Promise object returned at then() over-rides previous Promises.

Chaining the Promise

Let’s chain multiple Promises together.
1) The first promise is that if mom is happy she’ll give you the phone
2) Given 1), you then promise to show your friend the phone.

1)
Create the promise. If mom is happy, call resolve with the phone object.
If not happy, then call the reject with the error object.

2) Create the 2nd Promise

Chain em together

Let’s Chain the promises together. First, WillIGetNewPhone is the first promise. It runs, and when it resolves via .then, it will pass the phone object to the 2nd promise in obj showOff.

Once showOff resolves, it will then go to its resolve function definition and do the display.

finally, don’t forget to call askMom().

Mom, Dad example

Similarly

Waiting for all tasks to be done

Promise All

Promise All runs all its promises parallel. When all of its promises are done, it will then run its resolve.

Usages

https://medium.com/@ivantsov/promises-in-js-one-more-interview-question-6d59634a3463

Given:

Example 1

output:

foo start
new Promise in foo
foo Promise created and returned
foo resolved…!
bar start
new Promise in bar
bar Promise created and returned
bar resolved…!
result: bar resolved
finalResult: undefined

The reason why finalResult is undefined is due to:

Thus, bar() returns an object that resolves. The then() captures it and then at this point, there is nothing. Hence, we need to return another Promise object like so:

in order to propagate data further onto the next then().

Errors

Handling errors is basically the 2nd parameter. Just implement a callback for it and handle the parameter of your callback.

await vs then

ref – https://dev.to/masteringjs/using-then-vs-async-await-in-javascript-2pma

await is simply syntactic sugar that replaces a .then() handler with a bit simpler syntax. But, under the covers the operation is similar.

The code that comes after the await (that is within the async function) is basically put inside an invisible .then() handler.

JavaScript will pause the async function’s execution until the promise settles. All code that is after the await will wait (block) until the await settles.

With then(), the rest of the function will continue to execute just like how async/await lets all code below the async function run. When the Promise settles, the then() will then executes. So in other words, all code below await, is very similar to having a then.

Therefore, await is just an internal version of .then() (doing basically the same thing). The reason to choose one over the other doesn’t really have to do with performance, but has to do with desired coding style or coding convenience. Certainly, the interpreter has a few more opportunities to optimize things internally with await, but it’s unlikely that should be how you decide which to use. If all else was equal, I would choose await for the reason cited above. But, I’d first choose which made the code simpler to write and understand and maintain and test.

Used properly, await can often save you a bunch of lines of code making your code simpler to read, test and maintain. That’s why it was invented.

There’s no meaningful difference between the two versions of your code. Both achieve the same result when the axios call is successful or has an error.

Where await could make more of a convenience difference is if you had multiple successive asynchronous calls that needed to be serialized. Then, rather than bracketing them each inside a .then() handler to chain them properly, you could just use await and have simpler looking code.