JavaScript async await
A js async function can be used as a way to define a special kind of asynchronous function. These async functions can be used in conjunction with the await keyword to help with the process of writing asynchronous code easier in javaScript as of late specs of javaScript as of ECMAScript 2017.
These kinds of async functions still operate in the main event loop, so they still can not be used as a way to achieve what is often called true threading with javaScript, at least not by themselves. So then js async is not a replacement for Webworker in client side javaScript, or something like the cluster module, or child process module in nodejs. If you want to get closer to true threading you would want to look into those options and not just use asnyc functions alone. Still in some situations the async keyword can be useful so lets look at some code examples of this in use.
1 - js async basics
In this section I will be going over just a few very basic examples that involve the use of promises and the async keyword as a way to create functions, as well as other related topics when it comes to the very basics of this sort of thing. The main thing to keep in mind where is that the use of these async functions are just another way to operate in a single event loop, so if you are thinking that this is something that is far beyond using something like setTimeout that is not really the case actually. The reason why is because that setTiemout and async functions are still working within a single event loop. So if you are thinking that async functions are another kind of web worker, or spawn method call in nodejs, that is not how to think about it. However async functions are another tool along side features like setTimeout, requestAnimaitonFrame, and the Promise constructor.
It should go without saying then that this is not a getting started type post with javaScript, or functions in general in javaScript. However if you have at least some background with the very basics of getting started with javaScipt, in this section I will be sticking to a few simple examples that might hopefully show what async functions are, and also in the process hopefully also what they are not. After that I will be getting to some additional stuff that has to do with really getting into how to go about doing async type tasks with javaScipt that have to do with creating a whole other event loop.
1.1 - The source code here is on github
This post like many others is still a kind of work in progress, as such it is only a matter of time until I get around to editing the content here once again, as long as I am able to do so. With that said I have the collection of source code that I am writing about in this post up on my test vjs Github respiratory, along with all the other source code examples for all my other posts on native javaScript features. So then the latest work that I have done with these examples will be there, that is also where one would want to make a pull request. However there is also the comments section at the end of this post that can also be used to bring something up.
1.2 - Hello world async function
To start off with maybe it would be best to compare what the return values are for a async function compared to say a function expression. When I have a function expression that returns a string, the return value is, well a string no surprise there. However the same will not always be true for an async function as when I call such a function the return value right away is not a string, but an object. That is because an async function will always return a promise, even if the return value is not one the return value will be wrapped in a promise object.
|
|
1.3 - Hello world promise function
So then there is having a similar result to a sync function by just getting into the habit of creating functions that return a promise. One way to go about returning a promise inside the body of a function would be to use the Promise Constructor.
|
|
1.4 - using then off of a promise object
The main thing about promise objects is not to just assign the promise object to a variable, but to call the then function off of the promise object and do what needs to be done with the result insdie the body of this then function call.
|
|
1.5 - The same example with js async
The async keyword can be used in combination with a function such as an arrow function to declare an async function. Inside the body of the async function the await keyword can be used as a way to pause the execution of the rest of the logic in the function until a function that was called with await is completed. The function that is called with await should be a function that will return a promise or another function created with the async keyword.
A basic example of an async function in javaScript might then look like this then:
|
|
The foo function returns a promise that resolves after a delay. When used inside the body of the func async function that execution of code is paused, and thus the string end is not logged to the console until the delay has completed. So this can be thought of as a cleaner style compared to just using promises.
1.6 - Async functions will still hold up the event loop
So an async function that has some code in it that might hold up the event loop will do so just like that of any other function in javaScript. This is because just like any other function in javaScript, we are still dealing with a single event loop when it comes to just using a kind of function alone. That is unless we take advantage of something that allows for us to create an additional event loop completely what is going on in an async function can still hold up the rest of a script. However do not just take my word for it run a few simple source code examples to see for yourself.
For example take into account the following:
|
|
In this example when the heavyAsync function is called it still ends up delaying the whole application. This is because I am still just working with a single event loop. So then in order to truly get around this limitation I will need to do something more beyond just using async and promises that will help me to spin up more than one event loop to work with, and pass data to and from this other event loop.
2 - The Async and await keywords are then NOT a replacement for WebWorker
An async function still operates in the main javaScript event loop, so it is not a way to go about accomplishing what is often called true threading in javaScript. However there are ways of doing that these days with javaScript, just not with async await, at least not by itself anyway. When it comes to client side javaScript the feature of interest to look into would be web workers, this is a way to go about creating an instance of an object that can be used to, and receive results back from a script that is running in a whole other event loop completely.
2.1 - I will need a way to host what I am working on by way of http rather than file
The thing about getting into web workers is that they are of of many things that will not work when it comes to opening up an html file by way of the file protocol. So then if you are still developing that way this is one of many things that will come up where you have to loosen security settings with your browser, or better yet just find a way to host what you are working on by way of the http protocol by setting up a basic web static web sever. I have wrote another post on a simple script that can be used with node in the from of a single stand alone file, however there is also learning how to do things like this by using a popular framework like express in nodejs.
|
|
2.2 - A basic example of a web worker
So now that I have a way to host an html file and some javaScript code by way of the http protocol rather that the file protocol I can now get into working out a simple hello world style web worker example.
I will want a ww-basic.js file that looks like this:
|
|
This script when used as the source code file for a web worker will respond to a message from the main event loop by just appending what is passed to it to the string bar, and send that back as a message. Nothing special but this is a basic example of this that I am starting out where here in the section after all. So now that I have a script that I want to use for a web worker I will now want at least one html file, and a little additional javaScript code that will make use of this file.
|
|
When I go to this file in the web browser what I end up with is the string foo bar in the text area element. So then that seems to work okay as a basic example of a web worker at least when it comes to just getting started with this sort of thing. However maybe I should get around to making at least one more example of this to help really address what the deal is with this sort of thing and how it can help to really run code that will not bog down the rest of what is going on in the main event loop.
3 - In nodejs the child_process module can help to spin up more than one event loop
In nodejs there is the child_process built in module, and in this module there are methods like the exec method, and the spawn method that can be used to start a whole other process on the operating system on which node is running. This can be used to launch something from the command line such as a script that contains a shebang and made executable with the chmod command in Linux systems, an alias, or a binary, including node itself.
When doing so it results in an additional, independent process on the operating system. Thus it is a way to do something involving more than one event loop with javaScript, thus it is a kind of so called true threading that differs from what is typical when it comes to async functions, setTiemout, and so forth by itself. There is also the cluster module that is also worth checking out, but what is great about child process is that it can be used to run any kind of executable thing from the command line, not just javaScript.
|
|
|
|
So then this example, unlike the first one that just makes use of async await, does not hold up the main javaScript event loop.
3 - Conclusion
So then an async function is just a function that will always return a function, and inside the body of the function the await keyword can be used as a way to pause and wait for a result rather than moving on. I can not say that I use these kinds of functions that often actually as there are many ways of having a similar situation with things other than using async functions. There is having functions that return a function, and then there is also just doing things that involve old javaScriot style call back functions.
There are other late javaScript features that ate of greater interest to me, mainly web workers as that is a way to spin up a whole other event loop completely. Inside the score code of a file that I am using for a web worker, I could use async functions, but there are also many other options when it comes to delaying the calling of a function, or doing some kind of task that will finish at a later time.