For callback hell (Callback hell), presumably everyone is familiar with, especially for the front of friends, of course, the front of friends through a variety of ways to avoid callback hell, such as Promise. But for friends back end, especially after the rise of RxJava, Reactor and other reactive programming framework for the callback hell just hear more, but the less appear.
In order to better understand the callback hell Callback hell what the problem, we first need to learn how to write a callback hell. Before, we have to know what is the callback function.
This article will include:
What is a callback
Callback advantage
What the hell is a callback
Why is there a callback hell
What is the difference callback and Future
How to solve the callback hell
Today, we talk from the very beginning, to talk about what is the callback function.
What is a callback function?
On Baidu Encyclopedia, it says so:
The callback function is a function call through a function pointer. If you put the pointer (address) function as a parameter to another function, when the pointer is used to call the function it points to, we say this is a callback function. Callback function is not called directly by the parties to achieve the function, but by another calling party when a particular event or condition occurs, for response to the event or condition. Callback is a method call is any other method to its first argument of the method. In many cases, a callback method is when certain events occur is called.
what? Difficult to understand? Indeed difficult to understand and interpret this as well as pointers and so on, it is for java user unfriendly.
Give you an example, for your reference, also welcome criticism:
Recall: the caller after a call to the called party, the called party will be the results back to the caller. (A calls B, B after completion, the results back to A)
For example: your boss employee a job, employees to complete. After the staff to complete the work, the boss feedback results of the work. This process is called a callback.
Callback example
This time is easy to understand a lot of it! Talk is cheap, Show me the code! Well, we will use this to write a simple example.
Callback example
Callback Interface
First of all, let's write a following Callbackinterface, the interface contains only one method for callback operations.
The boss is the feedback of the object, so the need to implement Callbackthis interface, overloaded callbackmethods; for specific boss to do, of course, is big business, so have the makeBigDealsmethods; the boss of course, can not be without an army, he needs a staff, we'll constructor he was to add a staff Worker, we later realized Worker class.
Employees class, quite simply, out of a job, completed just fine, the result can be returned. But how to complete the callback?
publicclassWorker{
public String work(String someWork){
return'result';
}
}
复制代码
It is easy to think of this idea is very logical thinking, but in the callback, we need to make some changes.
Make up the code callback
For employees, the need to know two things, who is the boss, need doing. Thus, the two input parameters, namely, the boss and job content. Specific content in two steps, first completing its mission, is to report to the boss.
Next, we complete the Boss class. In the callbackmethod, the received results came, and the results are processed, we only print out here; in the makeBigDealsprocess, the boss assigning work, staff to complete, if the complete process is asynchronous , it is 异步调用, if it is synchronized , the Shi 同步回调, we are here asynchronously.
In the new thread, we execute worker.work(Boss.this, someDetail), which Boss.thisis the current object, here we officially completed callback .
Worker worker = new Worker();
Boss boss = new Boss(worker); // 给老板指派员工
boss.makeBigDeals("coding"); // 老板有一个代码要写复制代码
The results are as follows. Can be seen in the results, the boss got off work after the completion of the distribution of work, after work, another thread notifies owners receive feedback "coding is done". So far, we have completed the asynchronous callback entire process.
INFO 2019 九月 20 11:30:54,780 [main] - 分配工作
INFO 2019 九月 20 11:30:54,784 [main] - 分配完成
INFO 2019 九月 20 11:30:54,784 [main] - 老板下班。。
INFO 2019 九月 20 11:30:54,787 [Thread-0] - Boss got: coding is done!
复制代码
Decoupling , the correction sub-process from the main process Decoupling. For the same input, that might be of a different approach. In the callback function, we have completed the main flow (e.g. the above Bosstype), for the sub-processes (e.g., the above process Workeris separated from the main flow out of the class). For the main process, we only care about the input and output of the sub-processes, that is input in the example above Worker.workparameters, and outputs the sub-process is the main process callbackparameters of the method.
Asynchronous callback does not block the main thread. The above example can be seen clearly, the staff did not work before the boss has been completed after work, when the work is completed, the owner will be notified by another thread. The boss in this process without waiting for the child process.
Callback Hell
The overall design
We will extend the above functions, work to the boss first product manager for design; the design is complete, the programmer to complete the coding. A schematic process shown in FIG.
Callback Hell
The tasks to Product Manager
First, write a Callback, a new internal product manager of Worker, in makeBigDealrealization of the main tasks of the methods, the task to Product Manager; in overloaded callbackmethod to obtain the output product manager.
new Callback<String>() {
private Worker productManager = new Worker();
@Override
public void callback(String s) {
System.out.println("产品经理 output: " + s); // 获取产品经理的输出
}
public void makeBigDeals(String bigDeal) {
System.out.println("Boss将任务交给产品");
new Thread(() -> {
this.productManager.work(this, bigDeal); // 异步调用产品经理处理过程
}).start();
}
}.makeBigDeals("design");
复制代码
Then output to the developer product manager
After the product manager to get the output, and then output to the developer. So we again achieved a Callbackinterface. Similarly, Callbackin the development of a new new Worker, in the codingprocess, calls Workerfor development; the overloaded callbackmethod, obtaining the result of the development process.
@Override
public void callback(String s) {
System.out.println("产品经理 output: " + s); // 产品经理的输出
String midResult = s + " coding";
System.out.println("产品经理设计完成,再将任务交给开发");
new Callback<String>() {
private Worker coder = new Worker();
@Override
public void callback(String s) {
System.out.println("result: " + s); // 获取开发后的结果
}
public void coding(String coding) {
new Thread(() -> coder.work(this, coding)).start(); // 调用开发的Worker进行开发
}
}.coding(midResult); // 将产品经理的输出交给开发
}
复制代码
Complete implementation
new Callback<String>() {
private Worker productManager = new Worker();
@Overridepublicvoidapply(String s){
System.out.println("产品经理 output: " + s);
String midResult = s + " coding";
System.out.println("产品经理设计完成,再将任务交给开发");
new Callback<String>() {
private Worker coder = new Worker();
@Overridepublicvoidapply(String s){
System.out.println("result: " + s);
}
publicvoidcoding(String coding){
new Thread(() -> coder.work(this, coding)).start();
}
}.coding(midResult);
}
publicvoidmakeBigDeals(String bigDeal){
System.out.println("Boss将任务交给产品");
new Thread(() -> this.productManager.work(this, bigDeal)).start();
}
}.makeBigDeals("design");
复制代码
Well, a simple callback hell is complete. Show me the result!
Boss将任务交给产品
产品经理 output: design is done!
产品经理设计完成,再将任务交给开发
result: design is done! coding is done!
复制代码
Callback hell brought what?
In the end what is a callback hell? Simply put, the callback hell is inside and set up a Callback Callback, but if nesting too much, as if falling into hell, so to hell with the callback argument.
Advantage: What the hell callback bring to us? In fact, the callback code the same as the pipe , received input, and outputs the processed contents to the next step . And callback hell, is a plurality of pipe connections, a process of forming, and the respective sub-flow (pipe) independently of one another. The distal end may be more familiar friends, for example Promise.then().then().then(), is formed of a plurality of process flow line.
Disadvantages: the callback method, although the sub-processes decoupling, but the callback code readability reduces complexity greatly increased.
Above, we mentioned asynchronous callback does not block the main thread, then use the Future will not be blocked, and asynchronous callback difference in what?
We write an example of using the asynchronous call to the Future:
logger.info("分配工作...");
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> worker.work(someDetail));
logger.info("分配完工作。");
logger.info("老板下班回家了。。。");
logger.info("boss got the feedback from worker: {}", future.get());
复制代码
In the above code, we can see that although Workerthe work is asynchronous, but the boss get the results of the work ( future.get()) when they have to wait, and wait for this process is blocked. This is the callback and Future a significant difference.
How to solve the problem of callback hell, the most common is reactive programming RxJava and the Reactor , there Kotlin of Coroutine coroutine, OpenJDK out of the Project Loom . Which have their own advantages, refrain from that.
to sum up
in conclusion:
What is a callback . The caller callback is invoked after the called party, the called party will feedback the results to the caller. (A calls B, B after completion, the results back to A)
Callback advantage . 1) sub-process and the main process decoupled. 2) an asynchronous call and do not block the main thread.
What callback hell . Hell is a callback function callback nested, and more to see =. =
Why the hell callback occurs . Each callback like a pipeline, receiving the output, the output after the processing result to the next pipe. Each independent processing pipeline, composed of a plurality of pipes entire process.
What is the difference callback and Future . 1) difference between the two mechanisms; 2) Future will be blocked while waiting for the results, but the callback does not block.
How to solve the callback hell . The most common is reactive programming RxJava and Reactor.