The relation between
You might have already heard about
async/await. If you haven’t or still didn’t get the relation between them, don’t worry we will cover that here completely.
What is “thenable” object?
The definition of
thenable object is the simplest thing in the world:
Any object that has a method named “
then”is called a “thenable” object.
This object (
obj) is a
thenable object is allowed to have any other property and method with any name as well, but it must have a method is named
then to be a
The relation between “thenable” object and “promise”?
promise object is just a
thenable object, because it has a
then method (which is used to access the result of a
settled promise). That’s it.
But keep in mind that this relation is not the other way around, which means that every
thenable object is not a
The relation between “thenable”, “promise” and “async/await”
then keyword is just a convention that has been defined to make life easier.
For instance, now we all know to access the result of a promise, we should call the
then method of it. The name is not
map or anything else that causes confusion.
This naming convention has also helped us to have
Look that the code below and see the magic:
If you are not familiar with IIFE function check this article.
You probably have already used
async/await syntax in your codes and know how to used it.
But do you also aware that how
We are not going to fully cover the behind of the scene of
async/await here. However, if you are curious about it (and you should be), you can check this article out to get the main idea of how it works.
Brief explanation of how “
You should know that whenever you put an
then method of that object.
async/await syntax is implemented by
generator function and
await keyword is exactly used instead of
yield keyword, so the
async function needs to be resumed after calling the
then method. In order to handle this operation,
async function also sends a callback to the
then method as a parameter that contains the functionality for resuming itself.
I know it sounds a little bit fuzzy and for getting the idea better, you should check out this sample code:
You can run this code and see the result yourself.
If you look at the output, you can see that almost everything works as expected. But we still don’t have the result of the last
console.log(‘end’) and the operation is kind of freezing in that point.
The reason of this freezing is because the callback function which has been sent to the
then method has not been called yet to resuming the
In order to solve the problem, we should just call the callback to continue the operation.
Also if you send any value to the callback as its parameter, you will get it by the
await keyword (see the code below):
And now everything worked perfectly.
I guess till here you got the idea of what we are talking about and you might find out that how
knex and some other libraries work with some tweaking the code.
As a reminder, these libraries can be chainable and whenever you put an
await keyword in behind of them or call the
then method in their chain, they work exactly like a
In the following we are intending to walk through a simple example of a chainable object that would be ran by
await keyword and/or
The functionality that we expect from this stupid example that we are going to implement is to have some simple math methods (i.e.
div) and whenever we use it with
await keyword, it would run the main asynchronous operation and returns the corresponding result (which can be
The main asynchronous operation would be fulfilled if the reminder of the final value is divided by 2 be greater than zero — or not equal to zero (
n % 2 !== 0) — and otherwise it would be rejected.
Now we have an asynchronous function, let’s implement another simple function which can be chainable.
Note: I just refuse to use
thiskeyword here to avoid confusion that some people might have with it.
Now this function (
mathOp) can be used in this way:
It’s time to get to the main point and add the magical
then method to this chainable object and run the
asyncFunction inside of it. Afterward just return the result of it (which is a
Reminder: Don’t forget the callback function is going to be sent by
await keyword automatically.
This is the whole implementation of the
then method. It is simple, isn’t it?
Let’s put it inside the
And now you can run the code below to see the result:
Up until now it sounds that it works perfectly, but let me remind you that we didn’t handle the error that is caused by the
rejection state of the
First of all, to handle the errors, we need a
catch method beside of the
then method as well.
Put this method next to
then method inside of
There is nothing special about
catch method and we just added it that we could use it on chaining methods ourselves — which works like
then method on chaining and also send the callback to the
catch method on the returned
In the next step for handling errors we need to tweak our
If you wonder why we need to change the
then method to handle the errors and what is the relation between them, let me tell you another secret of
I have to admit that I already lied to you about that
await keyword that I said it just sends one callback on calling the
then method, I’m sorry about that guys, because it sends two callbacks.
As a reminder we should mention that the
then method on
promise object takes two callbacks, but the second one is arbitrary which is used as a callback for catching errors — just like
If you are curious about how
promise works, you should check out this book.
If you change the
then method body like the code below, you would see the same output as below:
Great! Now we can also use
mathOp function with
await keyword inside of a
try/catch block to handle the errors.
We are done with handling errors and the whole functionality of our stupid example.
At the end we can also do some fancy stuff to have a little cleaner code.
I hope you found this article useful.
If there is any unclear or ambiguous part, please feel free to ask your questions in the comment section or you can send me message directly.