JavaScript callback function (schema) principle and example in-depth analysis

Source: Internet
Author: User
Tags types of functions

The vast number of netizens read my previous discussion of the JavaScript principle this article is easy to understand
The callback function comes from a well-known programming paradigm-functional programming, at the basic level, functional programming specifies the parameters of the function. Functional programming Although the current scope of use has become smaller, but it has been "professional smart" programmers as a kind of difficult to understand technology, previously, and the future will be so.
Fortunately, functional programming has been elaborated by the General people like you and me can also understand and use. One of the main techniques of functional programming is the callback function, which you will soon read that implementing a callback function is as simple as passing a generic parameter variable. This technology is so simple that I wonder why it is often included in the high-level topic of JavaScript.
What is a callback or advanced function? The
callback function is considered an advanced function, an advanced function that is passed as a parameter to another function (which is called "otherfunction"), and the callback function is called (or executed) within the otherfunction. The essence of a callback function is a pattern (a pattern that solves common problems), so a callback function is also called a callback pattern.
Consider the following callback functions that are commonly used in jquery:
//note The item in the click Method's parameter is a function, not a variable.
The item is a callback function
$ ("#btn_1"). Click (function () {
  alert ("BTN 1 Clicked");
});
as seen in the previous example, we pass a function to the parameter of the click Method, and the click Method invokes (or executes) the callback function we pass to it. This example gives a typical way to use the callback function in JavaScript and is widely used in jquery.
Take a look at a typical example of another basic javascript:
var friends = ["Mike", "Stacy", "Andy", "Rick"];
Friends.foreach (function (eachname, index) {
Console.log (Index + 1 + "." + Eachname); 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
Once again, we passed an anonymous function in the same way (a function without a function name) to the Foreach method as a foreach parameter.
So far, we have passed an anonymous function as a parameter to another function or method. Before looking at other more complex callback functions, let's take a look at how callbacks work and implement a callback function of our own.
callback function be implemented?
We can use a function like a variable, as an argument to another function, in another function as the return result, and call it in another function. When we pass a callback function as a parameter to another function, we pass only the definition of the function and do not execute it in the argument.
when the containing (called) function has a callback function defined in the parameter, it can be called (that is, callback) at any time.
This means that the callback function is not executed immediately, but rather "callback" it (as its name) at the location specified in the function body containing the function. So, even if the first jquery example looks like this:
//the anonymous function is not being executed there in the parameter. 
//the item is A callback function
$ ("#btn_1"). Click (function () {
  alert ("BTN 1 Clicked");
}); The
anonymous function is called in the function body of the Click Function, and can be accessed by the containing function through the arguments object, even if there is no name.
The callback function is a closed packet.
When you pass a callback function as a parameter to another function, the callback function is executed somewhere within the body of the containing function function, as if the callback function is defined in the body of the function that contains the function. This means that the callback function is closed, want to know more about closures (http://blog.csdn.net/luozhonghua2014/article/details/45585835), and from what is known, the closure function can access the scope of the containing function, so, A callback function can access a variable that contains a function, even a global variable.
Basic principles of implementing callback functions
Simply put, there are a few principles to follow when implementing a callback function yourself.
use a named function or an anonymous function as a callback
In the preceding jquery and foreach examples, we define anonymous functions in the parameters that contain the function, which is one of the common forms of using the callback function, and the other is often used in the form of defining a function with a name and passing the function name as an argument to another function, for example:
?//global variable
var alluserdata = [];
Generic Logstuff function, prints to console
function Logstuff (userData) {
if (typeof userData = = = = "string")
{
Console.log (UserData);
}
else if (typeof userData = = = = "Object")
{
For (var item in UserData) {
Console.log (item + ":" + Userdata[item]);
}
}
}
A function that takes and parameters, the last one a callback function
function GetInput (options, callback) {
Alluserdata.push (options);
callback (options);
}
When we call the GetInput function, we pass Logstuff as a parameter.
So Logstuff would be is the function that would called back (or executed) inside the GetInput function
GetInput ({name: "Rich", Speciality: "JavaScript"}, Logstuff);
Name:rich
Speciality:javascript
passing parameters to the callback function
Because the callback function is executed just like a normal function, we can pass parameters to it. You can pass a callback function as a parameter to any property that contains a function (or a global property). In the previous example, we passed the options containing the function as arguments to the callback function. The following example lets us pass a global variable or local variable to the callback function:

Global variable
var generallastname = "Clinton";
function GetInput (options, callback) {
Alluserdata.push (options);
Pass the global variable generallastname to the callback function
Callback (Generallastname, options);
}
Make sure the callback is a function before executing
Before calling, it is often advisable to ensure that callbacks passed in through parameters are a required function. In addition, making the callback function optional is also a good practice.
Let's refactor the GetInput function in the example above to make sure that the callback function is properly checked.


function GetInput (options, callback) {
Alluserdata.push (options);
Make sure the callback is a function
if (typeof callback = = = = "function") {
Call it, since we had confirmed it is callable
callback (options);
}
}
If the GetInput function is not properly checked (checking whether callback is a function or passed in by argument), our code will cause a run-time error.
problems with the callback function that contains this object
When the callback function is a method containing the This object, we must modify the method that executes the callback function to protect the contents of this object. Otherwise the This object will point to the Global Window object (if the callback function is passed to the global function), or to the containing function. Let's take a look at the following code:
Define an object with some properties and a method
We'll later pass the method as a callback function to another function
var clientdata = {
id:094545,
FullName: "Not Set",
Setusername is a method on the Clientdata object
Setusername:function (FirstName, LastName) {
This refers to the FullName property in this object
This.fullname = FirstName + "" + lastName;
}
}
function Getuserinput (FirstName, LastName, callback) {
Do and stuff to validate firstname/lastname here
Now save the names
Callback (FirstName, LastName);
}
In the following example code, when Clientdata.setusername is executed, This.fullname does not set the property fullname in the Clientdata object, but instead sets the FullName in the Window object. Because Getuserinput is a global function. This behavior occurs because the this object points to the Window object in the global function.
Getuserinput ("Barack", "Obama", clientdata.setusername);
Console.log (clientdata.fullname);//Not Set
The FullName property is initialized on the Window object
Console.log (Window.fullname); Barack Obama Such a design is a disaster (discussed in the inheritance model)
Protect this object with the call or Apply function
We can solve the problem in the previous example by using the call or Apply function. So far, we know that every function in JavaScript has two methods: Call and apply. These methods can be used to set the contents of this object inside a function and to pass the content to the object that the function argument points to.
Call takes the value of used as the This object inside the function as the first parameter, and the remaining arguments To is passed to the function is passed individually (separated by commas of course). The Apply function ' s first parameter is also the value of be used as the thisobject inside the function and the last PA Rameter is a array of values (or the arguments object) to pass to the function. (Here is a description of how call or apply can be used to refer to an object or an array or any of the previous http://blog.csdn.net/luozhonghua2014/article/details/45585835) This sounds complicated, but let's look at how easy it is to use apply and call. To solve the problem in the previous example, we use the Apply function as follows:
//note that we have added a extra parameter for the callback object, called "Callbackobj"
function Getuserinput (FirstName, LastName, Callback, Callbackobj)  {
   //do other stuff to validate n Ame here
   //The use of the Apply function below would set the This object to be callbackobj
  &NBS P Callback.apply (Callbackobj, [FirstName, LastName]);
}
correctly sets the This object through the Apply function, and now we can execute the callback function correctly and it correctly sets the FullName property in the Clientdata object.
//We Pass the Clientdata.setusername method and the Clientdata object as parameters. The Clientdata object is used by the Apply function to set the This//object
? Getuserinput ("Barack", "Obama", CLI Entdata.setusername, Clientdata);
//The FullName property on the Clientdata is correctly set
Console.log (clientdata.fullname);//OBAMA
///////////together to execute a////////////Define an object with some properties and a method
We'll later pass the method as a callback function to another function
var clientdata = {
id:094545,
FullName: "Not Set",
Setusername is a method on the Clientdata object
Setusername:function (FirstName, LastName) {
This refers to the FullName property in this object
This.fullname = FirstName + "" + lastName;
}
}
Note that we have added a extra parameter for the callback object, called "Callbackobj"
function Getuserinput (FirstName, LastName, Callback, Callbackobj) {
Do and stuff to validate name here
The use of the Apply function below would set the This object to be callbackobj
Callback.apply (Callbackobj, [FirstName, LastName]);
}
We Pass the Clientdata.setusername method and the Clientdata object as parameters. The Clientdata object is used by the Apply function to set the This//object
Getuserinput ("Barack", "Obama", Clientdata.setusername, Clientdata);
The FullName property on the Clientdata is correctly set
Console.log (Clientdata.fullname); Barack Obama
The FullName property is initialized on the Window object
Console.log (window.fullname);//Barack Obama Why is this? This is the window contains all the attributes, this principle will be in the next analysis////////////////////// We can also use the call function, but in this case we use the Apply function.
Multiple callback functions are also allowed
We can pass multiple callback functions to another function, just like passing multiple variables. This is a typical example of an AJAX function using jquery:
function Successcallback () {
Do stuff before send
}
function Successcallback () {
Do stuff if success message received
}
function Completecallback () {
Do stuff upon completion
}
function Errorcallback () {
Do stuff if error received
}
$.ajax ({
URL: "Http://fiddle.jshell.net/favicon.png",
Success:successcallback,
Complete:completecallback,
Error:errorcallback
});
Questions and solutions for "Callback Hell"
Asynchronous code execution is a simple way to execute in any order, and sometimes it is quite common to have many levels of callback functions, and you look like the following code. The messy code below is called "Callback hell" because it's a cumbersome code that contains a lot of callbacks. I saw this example in Node-mongodb-native, MongoDB drives node. js. The sample code is like this:
var p_client = new Db (' integration_tests_20 ', New Server ("127.0.0.1", 27017, {}), {' PK ': custompkfactory});
P_client.open (function (err, p_client) {
P_client.dropdatabase (function (err, done) {
P_client.createcollection (' Test_custom_key ', function (err, collection) {
Collection.insert ({' A ': 1}, Function (err, docs) {
Collection.find ({' _id ': New ObjectID ("Aaaaaaaaaaaa")}, function (err, cursor) {
Cursor.toarray (function (err, items) {
Test.assertequals (1, items.length);
Let ' s close the DB
P_client.close ();
});
});
});
});
});
});
You are unlikely to encounter this problem in your own code, but if you run into it (or stumble into it later), there are two ways to solve the problem.

name and define your function, and pass the function name as a callback instead of defining an anonymous function in the parameter list of the main function.
Modularity: Divide your code into modules so that you can spare a chunk of code to do special work. You can then introduce this model into your large application.

Implement your own callback function

Now you fully understand (I'm sure you understand that if you don't read it quickly again) JavaScript uses the features of the callback and see that the callbacks are used so simple but powerful. You should see if your code has the opportunity to use the callback function, and you can consider using callbacks when you have the following requirements:
Avoid duplicate code (dry-do not Repeat yourself)
It's better to implement abstractions where you need more common functionality (you can handle various types of functions).
Enhanced maintainability of code
Enhance the readability of your code
There are more custom features.
Implementing your own callback function is simple, in the following example, I can create a function to complete the work: Get user data, use user data to generate a common poem, use user data to welcome users, but this function will be a messy function, everywhere is if/else judgment, There are even many restrictions that cannot be performed on other functions that the application may need to process user data.
Instead, I let the implementation add a callback function, so that the main function gets the user data and can pass the user's full name and gender to the parameters of the callback function and execute the callback function to accomplish any task.
In short, the Getuserinput function is generic and can perform multiple callback functions with various functions.
First, setup the generic poem Creator function; It is the callback function in the Getuserinput function below.
function Genericpoemmaker (name, gender) {
Console.log (name + "is finer than fine wine.");
Console.log ("Altruistic and noble for the modern time.");
Console.log ("Always admirably adorned with the latest style.");
Console.log ("A" + gender + "of unfortunate tragedies who still manages A perpetual Smile");
}
The callback, which is the last item in the parameter, would be our genericpoemmaker function we defined above.
function Getuserinput (firstName, LastName, Gender, callback) {
var fullName = FirstName + "" + lastName;
Make sure the callback is a function
if (typeof callback = = = = "function") {
Execute the callback function and pass the parameters to it
Callback (FullName, gender);
}
}
Call the Getuserinput function and pass the Genericpoemmaker function as a callback:
Getuserinput ("Michael", "Fassbender", "Man", Genericpoemmaker);
Output
/* Michael Fassbender is finer than fine wine.
Altruistic and noble for the modern time.
Always admirably adorned with the latest style.
A man of unfortunate tragedies who still manages a perpetual smile.
*/
Since the Getuserinput function only handles input from the user data, we can pass any callback function to it. For example, we can pass a greetuser function like this.
function GreetUser (customerName, sex) {
var salutation = sex && sex = = = "Man"? "Mr.": "Ms.";
Console.log ("Hello," + Salutation + "" + customerName);
}
Pass the GreetUser function as a callback to Getuserinput
Getuserinput ("Bill", "Gates", "Man", GreetUser);
And this is the output
Hello, Mr Bill Gates.
As in the previous example, we called the same getuserinput function, but this time we performed a completely different task. As you can see, the callback function provides a wide range of functions. Although the example mentioned earlier is very simple, think about how much you can save and how to better abstract your code when you start using a callback function. Come on! When you get up in the morning, think about it before you go to bed at night, and think about it when you rest ...
We often note the following when using callback functions in JavaScript, especially today's web application development, in third-party libraries and frameworks
Asynchronous execution (such as reading a file, sending an HTTP request)
Event monitoring and processing
To set the timeout and time interval method
Generalization: Code simplicity

JavaScript callback function (schema) principle and example in-depth analysis

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.