zoukankan      html  css  js  c++  java
  • javascript 回调函数

    什么是回调函数?wikipedia定义。

     A reference to executable code, or a piece of executable code, that is passed as an argument to other code.

    Here’s a simple example that’s probably quite familiar to everyone, taken from jQuery:

    $('#element').fadeIn('slow', function() {
        // callback function
    });

    This is a call to jQuery’s fadeIn() method. This method accepts two arguments: The speed of the fade-in and an optional callback function. In that function you can put whatever you want.

    When the fadeIn() method is completed, then the callback function (if present) will be executed. So, depending on the speed chosen, there could be a noticeable delay before the callback function code is executed. You can read more about jQuery’s callback functions here.

    How to Write a Callback Function

    If you’re writing your own functions or methods, then you might come across a need for a callback function. Here’s a very simple example of a custom callback function:

    function mySandwich(param1, param2, callback) {
        alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
        callback();
    }
    
    mySandwich('ham', 'cheese', function() {
        alert('Finished eating my sandwich.');
    });

    Here we have a function called mySandwich and it accepts three parameters. The third parameter is the callback function. When the function executes, it spits out an alert message with the passed values displayed. Then it executes the callback function.

    Notice that the actual parameter is just “callback” (without parentheses), but then when the callback is executed, it’s done using parentheses. You can call this parameter whatever you want, I just used “callback” so it’s obvious what’s going on.

    The callback function itself is defined in the third argument passed to the function call. That code has another alert message to tell you that the callback code has now executed. You can see in this simple example that an argument passed into a function can be a function itself, and this is what makes callbacks possible in JavaScript.

    Here’s a JSBin that uses the simple example above.

    Make the Callback Optional

    One thing you’ll notice about jQuery callbacks is that they’re optional. This means if a method accepts a callback, it won’t return an error if a callback is not included. In our simple example, the page will return an error if we call the function without a callback, like this:

     mySandwich('ham''cheese');  

     

    You can see this in action here. If you open your developer tools, you’ll see an error that says “undefined is not a function” (or something similar) that appears after the initial alert message.

    To make the callback optional, we can just do this:

    function mySandwich(param1, param2, callback) {
        alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
        if (callback) {
            callback();
        }
    }
    
    mySandwich('ham', 'cheese');

    Now, since we’re checking to ensure the existence of callback, the function call won’t cause an error without it. You can test this example here.

    Make Sure the Callback is a Function

    Finally, you can ensure that whatever value is passed as the third argument is in fact a proper function, by doing this:

    function mySandwich(param1, param2, callback) {
        alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
        if (callback && typeof(callback) === "function") {
            callback();
        }
    }
    
    mySandwich('ham', 'cheese', 'vegetables');

    Notice that the function now includes a test using the typeof operator, to ensure that whatever is passed is actually a function. The function call has a third argument passed, but it’s not a function, it’s a string. So the test usingtypeof ensures no error occurs.

    Here’s a JSBin with a nonfunction argument passed as the callback.

    A Note About Timing

    Although it is true that a callback function will execute last if it is placed last in the function, this will not always appear to happen. For example, if the function included some kind of asynchronous execution (like an Ajax call or an animation), then the callback would execute after the asynchronous action begins, but possibly before it finishes.如果函数包含异步调用函数,回调函数可能发生在异步函数之后或之前。

    Here’s an example that uses jQuery’s animate method:

    function mySandwich(param1, param2, callback) {
        alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
      
        $('#sandwich').animate({
            opacity: 0
        }, 5000, function() {
            // Animation complete.
        });
      
        if (callback && typeof(callback) === "function") {
            callback();
        }
    }
    
    mySandwich('ham', 'cheese', function() { 
        alert('Finished eating my sandwich.');
    });

    And again here’s that code live.

    Notice that although the callback appears later in source order than the animation, the callback will actually execute long before the animation completes. In this case, solving this problem is easy: You just put the callback execution inside the animate method’s callback function (where it says “Animation complete”).尽管回调函数出现在animation之后,但实际在动画结束前执行,解决这个问题是很容易的,把回调函数放在animate的参数里。

    This doesn’t cover all the details regarding asynchronous functions, but it should serve as a basic warning that callback functions will only execute last as long as all the code in the function is synchronous.

    via:http://www.impressivewebs.com/callback-functions-javascript/

    另一篇文章:

    Callback functions are extremely important in Javascript. They’re pretty much everywhere. Originally coming from a more traditional C/Java background I had trouble with this (and the whole idea of asynchronous programming), but I’m starting to get the hang of it. Strangely, I haven’t found any good introductions to callback functions online — I mainly found bits of documentation on the call() and apply() functions, or brief code snippits demonstrating their use — so, after learning the hard way I decided to try to write a simple introduction to callbacks myself.

    Functions are objects  函数就是对象

    To understand callback functions you first have to understand regular functions. This might seen like a “duh废话” thing to say, but functions in Javascript are a bit odd.

    Functions in Javascript are actually objects. Specifically, they’re Function objects created with the Function constructor. A Function object contains a string which contains the Javascript code of the function. If you’re coming from a language like C or Java that might seem strange (how can code be a string?!) but it’s actually run-of-the-mill for Javascript. The distinction between code and data is sometimes blurred.

    // you can create a function by passing the
    // Function constructor a string of code
    var func_multiply = new Function("arg1", "arg2", "return arg1 * arg2;");
    func_multiply(5,10); // => 50

    One benefit of this function-as-object concept is that you can pass code to another function in the same way you would pass a regular variable or object (because the code is literally just an object).

    Passing a function as a callback

    Passing a function as an argument is easy.

    // define our function with the callback argument
    function some_function(arg1, arg2, callback) {
        // this generates a random number between
        // arg1 and arg2
        var my_number = Math.ceil(Math.random() *
            (arg1 - arg2) + arg2);
        // then we're done, so we'll call the callback and
        // pass our result
        callback(my_number);
    }
    // call the function
    some_function(5, 15, function(num) {
        // this anonymous function will run when the
        // callback is called
        console.log("callback called! " + num);
    });

    It might seem silly to go through all that trouble when the value could just be returned normally, but there are situations where that’s impractical and callbacks are necessary.

    Don’t block the way

    Traditionally functions work by taking input in the form of arguments and returning a value using a return statement (ideally a single return statement at the end of the function: one entry point and one exit point). This makes sense. Functions are essentially mappings between input and output.

    Javascript gives us an option to do things a bit differently. Rather than wait around for a function to finish by returning a value, we can use callbacks to do it asynchronously. This is useful for things that take a while to finish, like making an AJAX request, because we aren’t holding up the browser. We can keep on doing other things while waiting for the callback to be called. In fact, very often we are required (or, rather, strongly encouraged) to do things asynchronously in Javascript.

    Here’s a more comprehensive example that uses AJAX to load an XML file, and uses the call() function to call a callback function in the context of the requested object (meaning that when we call the this keyword inside the callback function it will refer to the requested object):

    function some_function2(url, callback) {
        var httpRequest; // create our XMLHttpRequest object
        if (window.XMLHttpRequest) {
            httpRequest = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            // Internet Explorer is stupid
            httpRequest = new
                ActiveXObject("Microsoft.XMLHTTP");
         }
    
        httpRequest.onreadystatechange = function() {
            // inline function to check the status
            // of our request
            // this is called on every state change
            if (httpRequest.readyState === 4 &&
                    httpRequest.status === 200) {
                callback.call(httpRequest.responseXML);
                // call the callback function
            }
        };
        httpRequest.open('GET', url);
        httpRequest.send();
    }
    // call the function
    some_function2("text.xml", function() {
        console.log(this);
    });
    console.log("this will run before the above callback");

    In this example we create the httpRequest object and load an XML file. The typical paradigm of returning a value at the bottom of the function no longer works here. Our request is handled asynchronously, meaning that we start the request and tell it to call our function when it finishes.

    We’re using two anonymous functions here. It’s important to remember that we could just as easily be using named functions, but for sake of brevity they’re just written inline. The first anonymous function is run every time there’s a state change in our httpRequest object. We ignore it until the state is 4 (meaning it’s done) and the status is 200 (meaning it was successful). In the real world you’d want to check if the request failed, but we’re assuming the file exists and can be loaded by the browser. This anonymous function is assigned tohttpRequest.onreadystatechange, so it is not run right away but rather called every time there’s a state change in our request.

    When we finally finish our AJAX request, we not only run the callback function but we use the call() function. This is a different way of calling a callback function. The method we used before of just running the function would work fine here, but I thought it would be worth demonstrating the use of the call() function. Alternatively you could use the apply()function (the difference between the two is beyond the scope of this tutorial, but it involves how you pass arguments to the function).

    The neat thing about using call() is that we set the context in which the function is executed. This means that when we use the this keyword inside our callback function it refers to whatever we passed as the first argument for call(). In this case, when we refer to this inside our anonymous callback function we are referring to the responseXML from the AJAX request.

    Finally, the second console.log statement will run before the first, because the callback isn’t executed until the request is over, and until that happens the rest of the code goes right on ahead and keeps running.

    Wrapping it up

    Hopefully now you should understand callbacks well enough to use them in your own code. I still find it hard to structure code that is based around callbacks (it ends up looking like spaghetti… my mind is too accustomed to regular structured programming), but they’re a very powerful tool and one of the most interesting parts of the Javascript language.

    via:http://recurial.com/programming/understanding-callback-functions-in-javascript/

     

  • 相关阅读:
    jQuery中的DOM操作
    jQuery选择器
    面试问题总结
    oracle日期操作
    Oracle报错:ORA-02064: distributed operation not supported
    JDK源码-String
    JDK源码-HashSet
    JDK源码-TreeMap
    JDK源码-Vector
    AJAX验证用户是否存在
  • 原文地址:https://www.cnblogs.com/youxin/p/2700822.html
Copyright © 2011-2022 走看看