What is asynchronous?
Typically, the code of an application runs linearly and directly, and there is only one task at a time.
If a function to run requires another function, then it needs to wait until the other function ends and returns the result, and as long as this happens, the entire program is actually stopped by the user.
For example, Mac users occasionally experience this as a spinning rainbow caster.
The operating system displaying this cursor actually states that the current program you are using should stop and wait for something else to take and it will take time to work, and hereby declare that it is not a worry and busy.
This is an unpleasant experience, and it does not take much use of computing power, especially in this era, when computers have multiple processor cores.
It’s time to wait for something else to end, while it can be left to another processing core to inform us at the end of the work.
This way you can get things done simultaneously, which is the basis of “asynchronous programming”.
Everything depends on the application environment you are using to provide asymmetrical tasks with different APIs. In the field of web programming, this is the web browser environment.
Asynchronous techniques are very important in programming, and especially in web programming. When a web application runs in a browser and runs a heavy batch of code without restoring control to the browser, it may seem that the browser is locked. This is called “blocking”.
In this case, the browser can not manage the user’s input and execute other tasks, and will continue until the controller returns from the processor to the browser.
For the following, we’ll look at some examples to understand the exact meaning of blocking.
In this example (+), as you see, an “event listener” is added to the button, until a button is clicked, it executes a time-consuming operation.
In this operation, 10 million dates are calculated and the result is displayed in the console. Then a paragraph will be added to the DOM.
This code is executed in the same way as it was written and the subsequent operation will not be executed until the previous operation is completed.
Note: The previous example is very unrealistic. We will never calculate a millionth date on a web application. This example is intended solely for the first idea of the subject.
In the second example (+), we simulate something that is a bit more realistic and more likely to be seen on a web page.
We block user interaction by rendering the UI. In this example we have two buttons:
A “Fill canvas” button, which when clicked, provides 1 million blue circles on the <canvas>.
A Click me for alert button that displays an alert when clicked.
If you click the first button and then quickly click on the second button, you will notice that the alert does not appear until the rendering of the circles is completed.
The first operation blocks the second operation until its completion ends.
Note: In this case, the code is ugly and our intention is merely to create a blocking mode, but this is a common problem that developers and real-world applications are always with that handwriting.
The thread is basically a single process that the program can use to perform the task. Each thread can execute only one single task at a time:
Task A -> Task B -> Task C
Each task is executed in sequence and the task must be completed before the task can be started.
As we said earlier, many computers now have multithreaded processors and can therefore run multiple tasks simultaneously.
Programming languages that can support multiple threads can run multiple processor cores simultaneously to run tasks.
Thread 1: Task A -> Task B
Thread 2: Task C -> Task D
Main thread: Render circles to canvas -> Display alert ()
This way the user interaction with the browser is not blocked.
Main thread: Task A -> Task C
Worker thread: Expensive task B
Considering this, take a look at this example (+). Keep browser console open.
In fact, this example is a rewrite of the previous example, which performed 10 million dates in a separate worker thread.
Now when you click the button, the browser can display the paragraph before the dataset is completed.
Thus, the first operation does not block the second operation.
Web developers are very useful, but they also have their own limitations. The most important limitation of webcasters is that they can not access the DOM.
So you can not expect a webmaster to do anything directly to update the UI. We can not render 1 million blue circles inside the worker, since its task is merely computation.
The second problem is that although the code does not have a blocking mechanism, it still remains intact.
This situation will be problematic in cases where the function of the results of previous processing is required. Consider the following yarn diagrams:
Main thread: Task A -> Task B
In this case, Task A performs a task like fetching an image from the server, and task B performs something like applying a filter to the image.
If you begin to run task A first and then start running B immediately, you will encounter an error, because the image is still not ready.
Main thread: Task A -> Task B -> | Task D |
Worker thread: Task C ———–> | | |
In this case, suppose that task D uses the results of both tasks B and C. If we can ensure that these results are both ready at the same time, then there will be no problem, but such a situation is unlikely.
If task D attempts to run when its input is not yet ready, it will run with an error.
Browser asynchronous features
Browsers allow us to perform some operations asynchronously to correct such errors.
Functions such as Promises allow you to specify an executable mode for an operation (for example, fetch an image from the server), and then wait to return the result before executing the next operation:
Main thread: Task A Task B
Promise: | __async operation__ |
Since the operation takes place elsewhere, while the asynchronous operation is being processed, the thread is not blocked. In the next section of this series of tutorials we will look at ways to write asynchronous codes.
The principles of modern software development are increasingly being developed around the use of asynchronous programming so that programs can perform multiple tasks simultaneously.
When you use more modern and powerful APIs, you’ll find more than just the way to run an asynchronous programmer task.
Writing asynchronous code is more difficult, and getting used to it takes a bit of time, but it’s going to be easier.
In the next sections of this series, we will look at why the importance of asynchronous code and code design methods prevent the problems encountered in this paper.