简单的回调用法示例

回调提供了一种扩展函数(或方法)功能而无需更改其代码的方法。这种方法通常用在模块(库/插件)中,其代码不应该被更改。

假设我们编写了以下函数,计算给定值数组的总和:

function foo(array) {
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        sum += array[i];
    }
    return sum;
}

现在假设我们想要对数组的每个值做一些事情,例如使用 alert() 显示它。我们可以在 foo 的代码中进行适当的更改,如下所示:

function foo(array) {
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        alert(array[i]);
        sum += array[i];
    }
    return sum;
}

但是,如果我们决定使用 console.log 而不是 alert() 呢?显然,每当我们决定用每个值做其他事情时,改变 foo 的代码并不是一个好主意。如果没有改变 foo 的代码,可以选择改变主意。这正是回调的用例。我们只需稍微改变 foo 的签名和正文:

function foo(array, callback) {
    var sum = 0;
    for (var i = 0; i < array.length; i++) {
        callback(array[i]);
        sum += array[i];
    }
    return sum;
}

现在我们可以通过改变参数来改变 foo 的行为:

var array = [];
foo(array, alert);
foo(array, function (x) {
    console.log(x);
});

异步函数示例

在 jQuery 中,获取 JSON 数据的 $.getJSON() 方法是异步的。因此,在回调中传递代码可确保在获取 JSON 之后调用代码。

$.getJSON() 语法:

$.getJSON( url, dataObject, successCallback );

$.getJSON() 代码示例:

$.getJSON("foo.json", {}, function(data) {
    // data handling code
});

以下将工作,因为数据处理代码可能会被调用之前实际接收到的数据,因为 $.getJSON 函数将未指定的时间长,因为它等待 JSON 不成立调用堆栈。

$.getJSON("foo.json", {});
// data handling code

另一个异步函数的例子是 jQuery 的 animate() 函数。因为运行动画需要一段指定的时间,所以有时需要在动画后直接运行一些代码。

.animate() 语法:

jQueryElement.animate( properties, duration, callback );

例如,要创建淡出动画,然后元素完全消失,可以运行以下代码。注意使用回调。

elem.animate( { opacity: 0 }, 5000, function() {
    elem.hide();
} );

这允许在函数完成执行后立即隐藏元素。这不同于:

elem.animate( { opacity: 0 }, 5000 );
elem.hide();

因为后者不等待 animate()(异步函数)完成,因此该元素立即被隐藏,产生不良影响。