
Asynchronous programming today is in demand, especially in web development, where application responsiveness is especially important. No one wants to wait for the application to “hang out,” even if at this time it performs a query to the database, sends an email, or works on other tasks that may take a long time. The client wants to get an answer to their action, the best - immediately. If your application is slow, you lose clients. When confronted with a hanging application, most often the user simply closes it and never returns. From the user's point of view, the application just hung, it cannot understand why this happened: whether it performs a complex operation or stopped working in principle.
We present the translation of the article by Skyeng backend developer Sergey Zhuk.Application responsiveness
Modern applications are most often responsive, but some tasks or operations, such as exchanging data over a network, file I / O, or database requests, can take a lot of time and significantly slow down an application. To prevent such operations from blocking the application, they can be run in the background, thereby hiding the delay they cause. At the same time, the application remains responsive because it can continue to perform other tasks, such as returning the control flow to the user interface or responding to other events.
')
Parallelism and asynchrony
When people see an asynchronous code, most often they immediately think: “Excellent, I can parallelize processes!”. Perhaps I will disappoint you, but in fact it is not. Asynchrony and concurrency are not the same thing. To catch this difference can be difficult, so let's try to figure it out.
If tasks are performed asynchronously, they do not block each other and the execution of one task does not depend on the completion of another. Parallelism, in turn, implies the launch of several separate tasks simultaneously as independent units of work.
Asynchrony:
Go and complete the task yourself . Let me know when you're done, and show the result. At this time I can continue to engage in their task.
Asynchronous code requires handling dependencies that arise when performing tasks, and this is implemented using callbacks. When a task is completed, the code notifies another task. Asynchronous code is basically about the task execution time (the order of events).

Parallelism:
Hire as many workers as you like, and divide the task between them to complete it faster, and notify me when you are done. I can continue to do other things, or if the task is urgent, I will stay and wait until you return with the results. Then I can build the final result from all the workers. Parallel execution often requires more resources, so here basically everything depends on hardware.

To understand the difference between asynchronous and parallel execution with a real example, let's compare two popular web servers: Apache and Nginx. They perfectly illustrate this difference. Nginx uses an asynchronous, event-based model while Apache uses parallel threads. Apache creates new threads for each additional connection, so here the maximum number of allowed connections depends on the amount of available memory in the system. When the connection limit is reached, Apache stops creating additional connections. The limiting factor in configuring Apache is memory (remember that parallel execution often depends on hardware). If the stream stops, the client waits for a response until the stream is free and can send a response.
Nginx does not work like Apache, it does not create new threads for each incoming request. Nginx has a main workflow (or several workers, often for one processor there is one workflow), which is single-threaded. This worker can handle thousands of connections "simultaneously" and does it asynchronously, in one thread, rather than in parallel in several threads.
Thus, “asynchronous” is how we build the system, this is a composition of processes independent of each other. By "parallel execution" is meant the execution of several processes at the same moment in time, and they may be related or not related to each other. With asynchronous execution, we process several tasks at once, and with parallel execution, we run several processes at once. It may seem that this is the same thing, but it is not. Asynchrony describes the structure, parallelism - the way to perform.
Asynchronous execution can be compared with input-output devices on your computer (mouse, keyboard, display). All of them are controlled by the operating system, but each of them is an independent part of the kernel. These processes run asynchronously, they can be parallel, but this is not necessary. Thus, to ensure consistency, you must create a link between these independent parts in order to coordinate them.
And what of this backend?
You can say that responsiveness is not so important on the back end. All these cool asynchronous javascript stuff happens on the frond, and your server just responds to requests, so the frond should be responsible for the application's responsiveness, but not you. Yes, this is true, but the server’s task is not limited to API responses. Sometimes you have to manage complex tasks, such as downloading videos. In this case, perhaps, responsiveness is not the key factor, but its absence leads to wasting resources, because the application has to be idle. It can wait for the completion of file system operations, network interactions, database queries, and the like. Often, these I / O operations are very slow compared to CPU calculations, for example, when we convert video files. And while we are slowly saving or reading the file, the processor is forced to be in standby mode instead of doing useful work. As we have already found out, instead of waiting, we can run these tasks in the background. How? Go ahead.
Asynchronous PHP
In JavaScript, out-of-the-box, built-in support and solutions for writing asynchronous code are available. There is also Node.js, which allows you to write asynchronous server applications. In JavaScript, we can use the setTimeout () function to demonstrate an example of asynchronous code:

When you run this code, we will see the following:

The setTimeout () function sends the code to the queue and executes it upon completion of the current call stack. This means that we break the synchronous flow of code and delay execution. The second call to console.log () is executed before the call to the queue inside the call to setTimeout ().
What about PHP? In PHP, we do not have suitable adapted tools for writing truly asynchronous code. There is no equivalent to setTimeout (), and we cannot simply postpone or queue the execution of any code. That is why such frameworks and libraries as Amp and ReactPHP began to appear. Their idea is to hide the low-level details of the language and give the user high-level tools that allow you to write asynchronous code and control the competitive execution of processes like JavaScript and Node.js.
Why should I use PHP if I have Node.js and Go?
This question often arises when it comes to asynchronous PHP. For some reason, many oppose the use of PHP for writing asynchronous code. Someone always suggests using Go or Node.js instead of PHP.
Tweet
assertchris perfectly describes such situations:

Of course, when PHP was first created, there was no goal to make it a programming language that you can use to create large complex applications. At that time, no one thought about either JavaScript or asynchrony. But now we have a completely different PHP, which already has its own functions for writing asynchronous code (for example, the stream_select () function).
Yes, you can use Go or Node.js to create asynchronous server applications, but this does not always solve the problem. If you already have a lot of experience with PHP, it will be much easier for you to simply study the libraries and tools that are suitable for your situation than to learn a new language and a new ecosystem. Tools like
ReactPHP or
Amp allow you to write asynchronous code in the same way you do in Node.js. These tools are quite advanced and have stable versions, so you can safely use them in production.
Not only CLI
I'm not going to write a chat, server or something like that. I just want to speed up the site.
It is customary to think that asynchronous code can only be used in CLI scripts. It is absolutely normal to integrate some asynchronous components into a traditional synchronous environment, even into a traditional web application. For example, you can receive a request, and then asynchronously call several different resources, and when these calls are made, you can continue the request-response life cycle, and the page will be displayed faster as a result.
Or you need to make some external API calls - for example, when a user completes a payment, you want to send an email or push notification. You can execute these API calls asynchronously, and then continue with your traditional synchronous code flow. There is no need to completely rewrite the application and delete everything that slows down the work. Just identify the bottlenecks that interfere with performance, and, quite possibly, they will be able to fix with asynchronous code.
Yes, asynchronous code in most cases is still used in CLI scripts, but it is not limited to real-time chats and servers. If you just want to speed up your site, you do not need to abandon your symfony or Laravel framework and create your own fully asynchronous application server.
Conclusion
Do not be afraid to learn a new paradigm. PHP is much more than "run the script, execute the code and die." You will be surprised when you realize that you can use the familiar PHP in a completely new way, as you have never used it! Asynchronous code and event-oriented programming will enhance your understanding of PHP and the possibilities of using this language. You do not need to learn a new language to write asynchronous applications just because "PHP is not the right tool" or "I have always done that, it cannot be improved." Just try it!
Well, we also remind you that we always have a lot of
interesting vacancies for developers!