在 Javascript 中,可以定义函数 X 并将其作为参数传递给另一个函数 Y。
这样的函数 X 称为回调函数
。
您能否在一些清晰的示例中解释为什么使用回调函数很有用(例如,发送一些带演示的 fiddle 链接)?我可以看到一个用处,它是代码的可读性,但我不确定这一点,因为带有回调的代码看起来更复杂。
唯一的用处是它在浏览器环境中使用和在 AJAX 中异步执行吗? 另一个 Javascript 实现(例如 Rhino )呢?回调在那里也有用吗?还是它们的用处仅取决于执行 Javascript 的环境?
谢谢
最佳答案
作为参数的回调
回调很有用,因为它们允许您使用代码“配置”一个函数。
这方面的原型(prototype)示例是一个排序函数,它允许您指定自己的排序标准。我将使用一个函数,该函数根据某些条件返回数组的最小值,因为它比排序更简单,但它仍然可以很好地用作示例:
function min(collection, property) {
if (collection.length == 0) {
return null;
}
var minIndex = 0;
var minValue = collection[0][property];
for (var i = 1; i < collection.length; ++i) {
if (minValue > collection[i][property]) {
minValue = collection[i][property];
minIndex = i;
}
}
return collection[minIndex];
}
var items = [
{ name: "John", age: 20 }, { name: "Mary", age: 18 }
];
alert(min(items, 'age').name); // prints "Mary"
See this code run 强>。 它有什么问题?
问题是虽然我们做了一些努力来创建一个可配置的 min
函数(它根据我们指定的任何属性找到最小值),它在一般意义上仍然非常有限,因为它只能根据一个属性找到最小值。
如果我们的数据是这样呢?
var items = [ "John/20", "Mary/18" ];
这不再是对象数组,而是格式化字符串数组。它具有与原始集合相同的数据,但结构不同。结果,原来的min
函数不能用来处理它。
现在我们可以编写另一个版本的min
它适用于字符串而不是对象,但这有点毫无意义(有无限多种方式来表示相同的数据)。对于特定情况,这可能是一种快速而肮脏的解决方案,但考虑一下库编写者的问题:他们如何编写一个对每个人都有用的函数,而不知道数据将如何构建每个案例?
救援回调
简单:制作min
通过允许其用户指定如何从数据中提取条件,功能更强大。这听起来很像“给出函数代码以从数据中提取条件”,这就是我们要做的。 min
将接受一个回调:
function min(collection, callback) {
if (collection.length == 0) {
return null;
}
var minIndex = 0;
var minValue = callback(collection[0]);
for (var i = 1; i < collection.length; ++i) {
if (minValue > callback(collection[i])) {
minValue = callback(collection[i]);
minIndex = i;
}
}
return collection[minIndex];
}
var items = [ "John/20", "Mary/18" ];
var minItem = min(items, function(item) {
return item.split('/')[1]; // get the "age" part
});
alert(minItem);
现在我们的代码终于可以重用了。我们可以轻松地将其配置为同时处理第一种和第二种类型的数据,而无需付出太多努力。
See the callback-enabled function handle both types of data 强>。这是我们获得极大灵 active 的结果,因为它允许用户以回调的形式提供代码作为我们功能的一部分运行。
异步编程中的回调
回调的另一个主要用途是启用异步编程模型。这在您安排操作完成但不希望程序在操作完成之前停止运行的所有情况下都很有用。
为了使其正常工作,您为操作提供回调函数并有效地告诉它:帮我完成这项工作,完成后给我回电。然后您可以自由地继续做任何您喜欢的事情,因为您知道当结果可用时您指定的函数将运行。
这在使用 AJAX 的网络中最为明显:您向网络服务器发出请求,收到响应后您以某种方式对其进行操作。您不想当场等待响应,因为这可能会花费很多时间(例如,如果存在连接问题)并且您不希望您的程序一直没有响应。
有关 AJAX 回调的示例,请参阅 jQuery 的文档 load
功能。
关于javascript - 回调函数的用处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7347156/