# JavaScript/Async

Without particular keywords and techniques, the JavaScript engine executes statements one after the next in the sequence of the written code. In most cases, this is necessary because the result of a line is used in the following line.
Lines 1 and 2 must be finished entirely before line 3 can be executed. This is the usual sequential behavior.
But there are situations where it is not necessary for the following statements to wait for the end of the current one. Or, you expect that an activity will run for a long time, and you want to do something else in the meanwhile. Such parallel execution has the potential to reduce the overall response time dramatically. That becomes possible because modern computers have multiple CPUs and are able to perform multiple tasks at the same time. In the above example, lines 1 and 2 may run in parallel. Moreover, the client/server architecture delegates activities across multiple servers.
Typical situations are long-running database updates, handling of huge files, or CPU-intensive computations. But even for simple-looking things like the rendering of an HTML page, a browser typically runs multiple tasks.

## Single-threaded

Natively, "JavaScript is single-threaded and all the JavaScript code executes in a single thread. This includes your program source code and third-party libraries that you include in your program. When a program makes an I/O operation to read a file or a network request, this blocks the main thread".
To reach the goal of simultaneous activities anyway, browsers, service workers, libraries, and servers offer additional appropriate interfaces. Their primary use case is the unblocking execution of HTTP and database requests; a smaller proportion focuses on CPU-intensive computations.
At the level of the JavaScript language, there are three techniques to achieve asynchronism - what 'feels' like simultaneity.
* Callback function
* Promise
* Keywords async and await
The basic technique is the use of callback functions. This term is used for functions that are passed as an argument to another function, especially - but not only - for functions that implement an asynchronous behavior.
A Promise represents the final completion or failure of an asynchronous operation, including its result. It steers further processing after the end of such asynchronous running operations.
Because the evaluation of Promises with .then and .catch may lead to hard-to-read code - especially if they are nested -, JavaScript offers the keywords async and await. Their usage generates well-arranged code comparable with try .. catch .. finally of traditional JavaScript. But they don't implement additional features. Instead, under the hood they are based on Promises.

## Strictly sequential? No.

To demonstrate that code is not always executed in strict sequential order, we use a script that contains a CPU-intensive computation within a more or less huge loop. Depending on your computer, it runs for several seconds.
Expected output:
* The core of the asynchronous function func_async is a loop where a mathematical computation is done [(3) line 14]. The loop needs more or less time depending on the given parameter.
* The return value of func_async is not a simple value but a Promise. [(2) line 6]
* func_async is invoked by doTask once per element of the given array. [(4) line 24]
* Because of the asynchronous nature of asyn_func the function doTask is executed totally before func_async runs! This can be observed by the program output.
* The await null [(1) line 5] is a dummy call. It suspends the execution of func_async, giving doTask the chance to continue. If you delete this statement, the output will be different. Conclusion: To make the function really asynchronous you need both keywords, async in the function signature and await in the function body.
* If you have a tool to observe your computer in detail, you can recognize that the three invocations of func_async doesn't run at the same time on different CPUs but run one after the next (on the same or on different CPUs).

## Callback

Passing a function as a parameter to an (asynchronous) function is the original technique in JavaScript. We demonstrate its purpose and advantage with the predefined setTimeout function. It takes two parameters. The first one is the callback function we are speaking about. The second is a number specifying the milliseconds after which the callback function is called.
If showMessage is invocated, it runs instantly. If showMessageLater is invocated, it passes showMessage as a callback function to setTimeout, which executes it after a delay of 3 seconds.

## Promise

A Promise keeps track of whether an (asynchronous) function has been executed successfully or has terminated with an error, and it determines what happens next, invoking either .then or .catch.
The Promise is in one of three states:
* Pending: Initial state, before 'resolved' or 'rejected'
* Resolved: After successful completion of the function: resolve was called
* Rejected: After completion of the function with an error: reject was called
Expected output:
When demoPromise is invoked, it creates a new Promise and returns it. Then, it performs the time-consuming action, and depending on the result, it invokes resolve or reject.
Next (in the meanwhile, the calling script has done other things), either the .then or the .catch functions behind the call to demoPromise are executed. The two functions accept an (anonymous) function as their parameter. The parameter given to the anonymous function is the value of the Promise.
Please notice that the last statement of the script has been executed previously.
Many interfaces to libraries, APIs, and server functions are defined and implemented as functions returning a Promise, similar to the above demoPromise. As long as it's not necessary that you create your own asynchronous functions, it's not necessary that you create Promises. Often it's sufficient to call an external interface and work only with .then or .catch (or the async or await of next chapter).

## async / await

The keyword await forces the JavaScript engine to run the script named behind await entirely - including the new Promise part - before executing the following statement. Hence, - from the standpoint of the calling script - the asynchronous behavior is removed. Functions with await must be flagged in their signature with the keyword async.
The use of async .. await allows you to work with the traditional try .. catch statement instead of .then and .catch.

## A realistic example

We use the freely available demo API https://jsonplaceholder.typicode.com/. It offers a small amount of test data in JSON format.
The steps of the example are:
* await fetch: Get the data behind the URL. The await part guarantees that the script will not continue before the fetch has delivered all data.
* json reads the stream which contains the resulting data.
* The resulting data is an array of 10 elements. Each element is in JSON format, e.g.:
* As an example, the script shows the complete data and some of its parts in the console.
Note: It's likely that you will run into a CORS error when you use an arbitrary URL.

## Exercises

    ... are available on another page (click here).

## See also

* Processes and Threads (in Node.js)
* Promises and 'async' (in Node.js)
* MDN: async
* MDN: Fetch API

## References

* ↑ Hiden threads in Node.js