Transferred from: http://blog.csdn.net/tywinstark/article/details/48447135#comments
Many people are asking what is a callback? Baidu came out of the basic answer is not correct, see only will make people more confused. Below try to use the simplest examples to help you clear up, because the callback is not a sentence definition can understand the concept, need to use a piece of text as a story to explain, callback as many important computer concepts, it is a historical culture, you need to know where it came from, used to do, Can be understood and applied in the actual production.
Callback, is a very basic concept, especially in today's nodejs birth and vigorous development has become more attention. Many friends learn Nodejs, learning for a long time has not touched the doorway, feel at last in Express writing Web program, there is such a feeling can only explain not learn to understand Nodejs, essentially say do not understand the callback, do not understand Nodejs.
Nodejs has three main core:
- Callback Callback
- Event Events
- Stream Streams
First to see what is not called callbacks, the following is a lot of users mistakenly think of the callback:
1/code Example 12 //the Foo function is intended to receive two parameters, any type A, and the function type CB, at the end to call CB ()3 functionFoo (A, CB) {4 Console.log (a);5 //Do something else6 //maybe get some parameters for CB7 varparam =math.random ();8 CB (param);9 }Ten //define a function called callback that will be passed as a parameter to Foo One varCallBack =function(num) { A console.log (num); - } - //call Foo theFoo (2, CallBack);
The above code is not a callback, the following points out which concepts are easy to confuse:
- variable callback, assigned to an anonymous function, but not because it is called callback, is called Callback
_ foo function of the second form parameter named CB, the same is called CB, and is not a callback okay
_ CB At the end of the Foo function code is called as CB (PARAM), not because CB is called in another function, but call it callback
Frankly speaking, the above code is a normal function call, the only special point is that because JS has a functional language features, you can receive functions as parameters. In C language, you can use pointers to functions to achieve similar effects.
To stop here, you notice that the title of this article is to interpret async, callbacks, and EventLoop, and that this sequence is useful for understanding, and that understanding callbacks is a prerequisite for understanding asynchrony.
When it comes to asynchrony, what is async? What is the difference between distribution and parallelism?
Return to the original, traced back to us is a good way to learn programming, do not want to have any advanced tools and concepts, and to think if we only have a browser to do the compiler and a notepad, with plain JS write an asynchronous code, how to write? Cannot use the event system and cannot use browser features.
xiaoming : Was the code above asynchronous?
Lao Yuan : Of course not, even if you change Foo to Asyncfoo is not. What's confusing here is that CB (PARAM) is called at the end of the Foo function.
Xiao Ming : It seems that the asynchronous code should actually be called at the end of the callback function, because the code will not be executed.
Lao Yuan : one definition of async is that a function call does not return the original code call, and after the CB (params) call is finished, it still returns to the tail of Foo, even if there is code after CB (params), they can be executed, which is a synchronous call.
Plain JS Async has a lot of writing, take the classic as an example:
1 //code Example 22 //= = Synchronous addition3 functionAdd (A, b) {4 returnA +b;5 }6ADD (1, 2)//= 37 8 //= = = Asynchronous addition9 functionLazyadd (a) {Ten return function(b) { One returnA +b; A } - } - varresult = Lazyadd (1);//result equals an anonymous function, which is actually a closed packet the //Our purpose is to do an addition, where result saves part of the addition, that is, the first argument and the subsequent arithmetic rule, - //This is the key to async by returning a closure that consists of an anonymous function that holds the outer parameter A, which is stored in the variable result. - //Extreme case var result = Lazyadd (1) (2); This extreme situation is not asynchronous, it is not different from synchronization. - + //Now you can write some other code. -Console.log (' Wait some time, doing some fun '); + //The actual production is not so simple, it may be waiting for some conditions to be set up, then to carry out the other half. A atresult = result (2)//= 3
The code above shows the simplest asynchronous. What we want to emphasize is that Async is asynchronous, callbacks are callbacks, and they don't have a half-dime relationship.
Ok, change the code below to see what is called a callback:
1 //code Example 32 //note or the Add, the essence is here, and then said3 functionAdd (A, b) {4 returnA +b;5 }6 //Lazyadd changed, one more parameter CB7 functionLazyadd (A, CB) {8 return function(b) {9 CB (A, b);Ten } One } A //pass add to formal parameter CB - varresult = Lazyadd (1, ADD) - //doing something else theresult = result (2);//= 3
This piece of code, seemingly simple, is not trivial.
Xiao Ming : This code gives a person's first feeling is to take off the pants fart, clearly a a+b, first became asynchronous writing a lot more code, people do not understand, now this adds the so-called "callback", more verbose, the final result is 1+2=3, is this not sick?
Lao Yuan : You only see the results, but do not know why people write so, so write for what. In code examples 2 and 3, the same add function is passed as a parameter to Lazyadd, at which point it is a callback. So why is the CB passed in Foo not a callback in code example 1? To understand this sentence carefully, you need a state to call the callback function, own state, where a closure is saved by the status of a.
Xiao Ming : I am a boy
Lao Yuan : Now again why to have a callback, see the output results, the callback in addition to verbose and difficult to understand the meaning of nothing. But!!!
Now say it, Callback's advantage is: ensure the API does not rip
In other words, async is very demanding, good processing can improve the efficiency of the calculation, not to wait for a card somewhere. But asynchronous notation, we see very ugly, put an addition into the asynchronous, are so ugly, not to mention the other. Then the beauty of callback is "to ensure that the API does not rip", the essence of the code to write, or the add, yes, so that the programmer in writing asynchronous programs, but also as well as the synchronous way to understand, add as callback incoming, The guarantee is that the Add method is good to understand, as an important part of the API design, to ensure that developers to use it easily, code readability is high.
Take Nodejs's ReadFile API as an example to further illustrate:
fs.readfile (filename, [options], callback)
There are two required parameters, filename and callback.
Callback is the actual programmer to write code place, write it when the assumption that the file has been read, how to write how to write, is the API history of a great progress.
// read the file ' etc/passwd ', after the read is completed will return the value, passing in function (err, data) this callback function. function (err, data) { ifthrow err; Console.log (data);});
Callbacks and closures have a common feature: Before the final "callback" call, all the previous states are saved.
This code for people's doubts is often, how do I know callback to receive a few parameters, the type of the parameter?
A: The API provider is designed in advance, it needs to explain in the document what parameters callback receive.
As shown in code 3, API designers have implemented the callback form through various techniques, which are painful to write. And Fs.readfile looks very lightweight, because it contains not only async, callbacks, but also new conceptual eventloop.
EventLoop is an earlier concept, such as the message loop in MFC, the event mechanism in the browser, and so on.
Then why should there be eventloop, and what is the purpose of it?
We use a simple pseudo-example to see how it works without EventLoop:
1 //code Example 42 functionAdd (A, b) {3 returnA +b;4 }5 6 functionLazyadd (A, CB) {7 return function(b) {8 CB (A, b);9 }Ten } One A varresult = Lazyadd (1, ADD) - //Suppose a variable button is false and we continue to invoke result when the button is true. - varbutton =false; the - //The common approach is the observer pattern, which sends a person to constantly see the value of the button, - //as soon as you change, you start executing result (2), and of course someone else has to change the value of the button. - //This assumes that someone has the ability to do something like a different thread. + while(true){ - if(Button) { +result = Result (2); A Break; at } - } - -result = result (2);//= 3
So if there are a lot of these functions, each one has to run an observer pattern, which looks like a comparison fee calculation under certain conditions. At this time EventLoop was born, sent a person to poll all, other people can put the observation conditions and callback function registered on the EventLoop, it for unified polling, the more people registered, polling a lap longer. But simplified programming, without everyone writing polling, providing the API is convenient, as fs.readfile as simple to understand, Fs.readfile read the file '/etc/ passwd ', register it on EventLoop, and when the file is read, EventLoop is aware of it by polling and invokes the callback function with ReadFile registration, here is funtion (err, data)
Say it again: under certain conditions, a single machine is replaced with space for calculation. Originally callback carried out on the unequal, there is a place, other dependent on it, with the observation mode has been staring at it, each polling their respective. Now someone has come out to poll for everyone.
Another way to say it again, the important thing, change the method said 3 times: on a single machine, unified polling looks relatively provincial, but also brings a lot of problems, such as Nodejs in single-threaded case, if a function computation is very complex, will hinder all other events, So it's going to be the case that the complex computations are given to other threads or services.
We have been emphasizing the single machine, if it is more than one, with a unified people to poll, it is more scary, we all register the event on a machine, it is responsible for polling all, this namenode is prone to collapse. So on more than one machine, and fit, each day the machine polling their respective, the problem is that the state is inconsistent. Well, this is where the program is interesting, and we need to know why the invention is eventloop, and we need to know where eventloop is having problems. The genius of the programmer, but also proposed a variety of consistency algorithm to solve this problem, this article is not discussed.
So far, we have combed the relationship between them:
Asynchronous –> callback –> EventLoop
Every progress is a step, all need wisdom to solve.
The callback also produced a lot of problems, the most serious problem is callback Hell callback hell.
1Fs.readfile ('/etc/password ',function(err, data) {2 //Do something3Fs.readfile (' xxxx ',function(err, data) {4 //Do something5Fs.readfile (' xxxxx ',function(err, data) {6 //Do something7 })8 })9})
This example may not be appropriate, but it can also be understood that a layer of code will appear in a similar situation, with poor readability and maintainability.
The generator is given in ES6 to solve the problem of asynchronous programming, and we are free to discuss it.
A detailed callback function--using JS as an example to interpret asynchronous, callback and EventLoop