在 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 。 它有什么问题?
问题是虽然我们做了一些努力来创建一个可配置的 如果我们的数据是这样呢? 这不再是对象数组,而是格式化字符串数组。它具有与原始集合相同的数据,但结构不同。结果,原来的 现在我们可以编写另一个版本的 救援回调 简单:制作 现在我们的代码终于可以重用了。我们可以轻松地将其配置为同时处理第一种和第二种类型的数据,而无需付出太多努力。 See the callback-enabled function handle both types of data 。这是我们获得极大灵 active 的结果,因为它允许用户以回调的形式提供代码作为我们功能的一部分运行。
回调的另一个主要用途是启用异步编程模型。这在您安排操作完成但不希望程序在操作完成之前停止运行的所有情况下都很有用。 为了使其正常工作,您为操作提供回调函数并有效地告诉它:帮我完成这项工作,完成后给我回电。然后您可以自由地继续做任何您喜欢的事情,因为您知道当结果可用时您指定的函数将运行。 这在使用 AJAX 的网络中最为明显:您向网络服务器发出请求,收到响应后您以某种方式对其进行操作。您不想当场等待响应,因为这可能会花费很多时间(例如,如果存在连接问题)并且您不希望您的程序一直没有响应。 有关 AJAX 回调的示例,请参阅 jQuery 的文档 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);
异步编程中的回调
load 功能。
关于javascript - 回调函数的用处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7347156/
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法