Original: http://javascriptissexy.com/
In Javascrip, a function is a built-in class object, meaning that it is a type of object that can be used as an object in the management of a built-in object as other objects of string, Array, number, and object. Because a function is actually an object, it can be "stored in a variable, passed by argument to (another) function, created inside a function, and returned a result value from a function." Because a function is a built-in object, we can pass it as an argument to another function, defer to execution in the function, or even return it after execution. This is the essence of using callback functions in JavaScript. The remainder of this article will learn about JavaScript's callback functions in general. The callback function may be the most widely used functional programming technique in JavaScript, and perhaps just a small piece of JavaScript or jquery code will leave the developer with a sense of mystery, and reading this article may help you eliminate the mystery.
callback functions come from a well-known programming paradigm--
functional programming , at the basic level, functional programming specifies the parameters of the function. Functional programming, although now used in a smaller scope, has been viewed by "professional and intelligent" programmers as a technology that is difficult to understand, as it was before, and in the future.
Fortunately, functional programming has been explained by the general people like you and I can 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. The technology is so simple that I wonder why it is often included in the top topics of JavaScript.
What is a callback or an advanced function?
A callback function is considered an advanced function, an advanced function that is passed as an argument to another function (called "otherfunction"), which is called (or executed) within the otherfunction. The essence of a callback function is a pattern (a pattern that solves common problems), so the callback function is also called a callback pattern. Consider the following callback functions that are commonly used in jquery:
The item in the "click Method" parameter is a function, not a variable.
The item is a callback function
$ ("#btn_1"). Click (function () {
alert ("BTN 1 clicked");
});
As we saw in the previous example, we passed a function to the parameter of the click Method, and the click Method will invoke (or execute) The callback function that we pass to it. This example gives a typical way to use callback functions in JavaScript and is widely used in jquery.
Savor another typical example of a 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 (a function without a function name) to the Foreach method in the same way, as a foreach parameter.
So far, we've passed an anonymous function as an argument to another function or method. Before looking at other more complex callback functions, let's understand how the callback works and implement a callback function of its own.
how the callback function is implemented.
We can use a function as a variable, as an argument to another function, as a return result in another function, and call it in another function. When we pass a callback function as a parameter to another function, we only pass the definition of the function and do not execute it in the parameter.
When the containing (calling) function has a callback function defined in the parameter, it can call (or callback) it at any time.
This means that the callback function is not executed immediately, but rather "callback" it (in its name) at the location specified in the function body containing the function. So, even the first jquery example looks like this:
The anonymous function is isn't being executed there in the parameter.
The item is a callback function
$ ("#btn_1"). Click (function () {
alert ("BTN 1 clicked");
});
Anonymous functions will be deferred in the function body of the Click function, even if there is no name, can be accessed by the arguments object by the containing function.
The callback function is a closed packet.
When passing a callback function as a parameter to another function, the callback function is executed somewhere in the body containing the function function, just as the callback function is defined in the function body that contains the function. This means that the callback function is closed and you want to learn more about closures, please refer to the author's other post understand JavaScript Closures with Ease. It is well-known that the closure function can access the scope of the containing function, so the callback function can access the variable that contains the function, even the global variable.
Basic principles for implementing callback functions
Simply put, you need to follow a few principles when you implement a callback function.
Use a named function or an anonymous function as a callback
In the preceding jquery and foreach examples, we define anonymous functions in parameters that contain functions, one of the common forms of using callback functions, 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 that prints to console
function Logstuff (userData) {
if (typeof userData = = "Strin G ")
{
console.log (userData);
}
else if (typeof UserData = = "Object")
{for
(var item in userData) {
Console.log (item + ":" + userdata[ite M]);
}} A function that takes two 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 arguments to callback functions
Because the callback function is executed in the same way as a normal function, we can pass arguments to it. You can pass any property (or global property) that contains a function as a parameter to the callback function. In the previous example, we passed the options containing the function as arguments to the callback function. The following example lets you pass a global variable or a 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 that the callback is a function before executing
Before calling, it is often advisable to make sure that the callback passed in by the parameter is a required function. In addition, it is also a good practice to make the callback function optional.
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 have confirmed It is callable
callback (options);
}
If the GetInput function does not do an appropriate check (check that the callback is a function, or whether it is passed in through a parameter), our code will cause a run-time error.
Problem with a callback function that contains the This object
When the callback function is a method that contains 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 Anoth er function
var clientdata = {
id:094545,
fullName: ' Not Set ',
//Setusername is a method on the CLIENTDA Ta object
setusername:function (FirstName, LastName) {
//This refers to the FullName
this.fullname = FirstName + "" + LastName;
}}
function Getuserinput (FirstName, LastName, callback) {
//do other stuff to validate Firstname/lastname c14/>//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 in the global function the this object points to the Window object.
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
Use the call or Apply function to protect this object
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 the This object inside the function, and the contents are passed to the object to which the function argument points.
Call takes the "the" is used as the This object inside the function as the the I parameter, and the remaining Arguments to is passed to the function are passed individually (separated by commas of course). The Apply function ' s the ' the ' also ' the ' parameter ' is used as the thisobject inside the function, while the last PA Rameter is a array of values (or the arguments object) to the function. (This paragraph is too clumsy to translate, put the original experience)
This may sound complicated, but let's see 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 (the Name, LastName, Callback, Callbackobj) {
//do other stuff to validate name here//the "Use of the"
Apply funct Ion below would set the This object to be Callbackobj
callback.apply (callbackobj, [FirstName, LastName]);
}
Set the This object correctly with the Apply function, now we can correctly execute the callback function and it correctly set 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", Clie Ntdata.setusername, clientdata);
The FullName property on the Clientdata is correctly set
console.log (clientdata.fullname);//Barack Obama
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 that uses 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
});
problems and solutions to "callback to Hell"
Asynchronous code execution is a simple way to execute in any order, sometimes it is very common to have many levels of callback functions, you look like the following code. The following messy code 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 drive node.js. 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're not likely to have this problem in your own code, but if you run into it (or come across it later), there are two ways to solve the problem. Name and define your function, and then pass the function name as a callback instead of defining an anonymous function in the main function's parameter list. Modularity: Dividing your code into modules so that you can empty out a chunk of code to do special work. You can then introduce this model into your large application.
to implement your own callback function
Now that you have fully understood (I believe you have understood, if not please read it quickly again) JavaScript uses the features of the callback and see that the callback usage is so simple but powerful. You should see if your code has a chance to use a callback function, and you can consider using callbacks when you have the following requirements: Avoid repetitive code (dry-do not Repeat yourself) to better implement abstractions where you need more common functionality (handles various types of functions). Enhanced code maintainability enhance code readability There are more customization features
It's simple to implement your own callback function, in the following example, I can create a function to do the work: Get user data, use user data to generate a generic poem, use user data to welcome users, but this function will be a messy function, everywhere is if/else judgment, There are even a lot of limitations and the inability to perform other functions that the application might need to process user data.
Instead, I let the implementation add a callback function so that the main function takes the user's data and then passes the user's full name and gender to the callback function and executes the callback function to accomplish any task.
In short, the Getuserinput function is generic, and it can perform multiple callback functions with various functions.
///The setup the generic poem creator function; it is the callback function in the Getuserinput function belo
W. function Genericpoemmaker (name, gender) {Console.log (name + "is finer than fine wine.");
Console.log ("Altruistic and noble for the modern");
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