你真的了解回调函数(Callback)吗?

作者: EfficLab实验室分类: 计算机技术 发布时间: 2024-04-12 00:01:53 浏览:56156 次

你真的了解回调函数(Callback)吗?

DA35:
就是把一个函数的引用交给另一个东西,另一个东西可以选择在任何时候去调用一下这个函数,这个函数就是回调函数。

【回复】简单粗暴的介绍[星星眼][星星眼][星星眼]给你点个赞
JQiue:
本质是因为函数在内存中拥有地址,地址是可以被传递的,这才是作为值进行传递的主要原因,在c中可以传递函数指针,在js中可以传递函数引用,即使是所谓的lambda表达式其实就是一个匿名的函数,返回了函数引用,没那么复杂。回调函数的主要作用就是异步编程,基于事件驱动的编程,以及函数式编程

【回复】回复 @不落不变 :打错特错,单纯的地址可不能实现闭包,参考cpp的可调用对象,它本质是一个类函数的类,此时要考虑闭包中的数据是否是引用传递还是值传递,闭包捕获的引用是否会在触发callback被使用时失效[doge]
【回复】后半段这样的高层是不稳定的,根本就不应该在这个层次进行讨论。尤其不该在提及函数地址的同时提及JS和lambda表达式(那些都完全是另一套东西)。 不过像你这样能做到每一点都对,组合起来并表达出来却能引起各种极大误解的人也是人才。
【回复】回复 @JQiue :引用确实可以类比指针,指针确实可以等同于内存地址 函数确实是可以被传递的 但 引用和地址是完全两个不同的概念啊 lambda表达式也不是函数啊 不同语言的lambda表达式也根本都是不同的东西啊 你把这些完全不同的东西放到一块都搞混了啊 一个根本没解释清楚的原理,还举了一大堆例子,新手看了你这个得被误导成什么样子 还是说你就喜欢这样一面对多面的语法错误啊
天外の飞兔:
回调函数,回调函数,意思就是做完一件事情后再回来调用的函数,这样的函数一般命名为callBack,这样一眼就可以看出来,这个函数会在你原本调用的函数做的事情做完之后,你原本调用的函数会去调用这个叫"回调"的函数。

【回复】回复 @Sybili :至于回到最初抽象层的问题,我可以举win api的窗口消息处理函数例子告诉你怎样算回到最初抽象层。 在这个例子下,我们主要关注2个抽象层,用户层和系统层。注意这里的“系统层”和“用户层”是软件设计的抽象层,而非指内核态和用户态。 一方面,用户层希望以简单易懂的方式处理各种窗口消息(win api给出的方式是消息循环),包括用户键鼠输入等;另一方面,在系统层,这些消息的本质是非连续的,随机的,由各种复杂系统产生的中断与信号。对于需要解决这个需求与现实的矛盾的系统来说,相关实现无疑是与底层密切相关的,必须于系统层完成的,而最终实现(对消息的具体处理)却是不确定,且拥有海量可能性的,需要由用户层完成。 用户层程序员通过将某些用户层程序作为回调通知系统,系统在完成部分处理后调用其提前设置的回调程序来协助其规划合适的执行时机,并接收回调程序返回值来处理错误。 “回到最初抽象层”就是说类似这样从用户层到系统层,并在回调中再次回到用户层的情况。 换句话说就是你设置回调是哪个设计层面的,通常你的回调程序也会处于哪个设计层面。(同样的,在其他特殊情况下,回调程序也可能与设置者不处于同一抽象层,但我认为这样的情况有比回调更好的处理方案,不做讨论) 同时这也是典型的非尾调回调,回调程序被调用时机是随机且不确定的(至少仅用户层看来是这样的),(系统层的)调用者在完成回调后依然会进行其他处理,而不是在所有处理结束后调用(不然你点一下鼠标电脑关机了程序才响应)。
【回复】回复 @晨夕星海 :因为我见过太多烂代码乱用回调,如果只是传了个execuable、能被 called later,就别称呼它为回调函数。我知道历史上就是么叫的,一九六几七几年的代码就是这么写的,lisp schema的早期论文里就有这种例子,可时而至今代码的复杂度早已不同往日,为什么很多开发框架要避开这些词,不是因为要推陈出新,而是它很容易滥用、概念很容易被误解,干脆就不用。光解释它因为能被传进另一个函数执行,为什么要叫它回调?凭什么?这个视频说清楚了么?
【回复】回复 @Sybili :你没用过事件挂钩?前置挂钩、后置挂钩同样是一种回调函数。前置挂钩可以阻止事件、更改事件参数。后置挂钩可以敲定事件返回值。一个空壳事件可以由调用方利用后置回调决定事件内容,也可以由第三方利用前置挂钩绕开后续内容。
一级有大:
小心回调层数过多,导致回调地狱,最后都不知道真实执行的是哪段代码了

【回复】回复 @Sybili :应对回调的正确的做法不是尾调,因为编译器根本无法对不确定的回调函数进行尾调优化(只有递归这样确定的才能) 正确的做法是在设计时避免在回调设计中嵌套回调设计(规定回调函数不可以调用其他回调函数),或执行流规划(目的同样是确保不在回调函数中调用回调)。
【回复】callback hell正是对 callback的滥用,健康的 callback应该放在最后并且不依赖它的返回值(尾调用),编译器很容易对这种情况进行优化
【回复】回调地狱好像是层级过多导致代码难以阅读,一般只有异步里面会出现这个问题,现在有Promise基本是能够解决了,你说的回调层级过多应该不存在,除非间接的实现了递归,这也不是回调的问题,是你代码写错了
寂寞的欧尼酱:
回调函数的本质是指针,理解这个之后,后面的内容就很容易理解。 - 讲解形式不建议这么书面(或着说不要照本宣科,将课本、PPT 那种情况),使用通俗的说法。 - 减少文字的出现,很多时候文字会参杂很多不相关的信息,阻碍理解本质。 - 建议使用更多的动画和更普遍的例子帮助理解。

【回复】不同语言也有不同叫法,比如委托,事件[doge]
MiskuZero:
回调这个词还是接触vue的时候遇到的,之前学js的时候就接触过事件的注册与监听,只是没想到一块儿去。 然后又玩了下java的gui编程,用的还算熟练,网上也查过回调的概念,还是没理解。然后遇到了gui里的一个Image类,发现里面有个Observer参数,很是好奇,但又没多想。后来又了解了设计模式,里面有个观察者模式,原来就是说的这个啊,但是也没和回调想到一块儿。然后今天看这个视频发现回调原来就这啊,然后又说是什么发布订阅模式,啊这,这不就是观察者模式的另一个说法吗[笑哭]。 不懂为什么一个概念原来在同一个领域还有这么多说法,如果没看到这个视频,我根本就不会想到这些概念居然还会有联系,这么多说法原来都是在描述同一件事...

【回复】你被误导了,你说的事件注册监听、观察者模式是相似的一回事,但它们都不能叫回调,前者是只响应事件(有时效上的微弱区别),后者是在完成本职工作后再顺带走进下个流程,一定要注意它是完成本职工作后,回调不是它的主要目的,不然就不应该叫回调
【回复】领域不一样吧,在不同领域趋向的作用不同,换个名称在特定领域里面也许更好理解。回调函数我觉得制定的范围比较比较广的,广泛意义上“在做完某件事后,才调用”,不局限在观察者,多态(这个可能不是很恰当),异步通知,消息队列这些杂七杂八上的应用都有回调的概念,当然了这是个人见解,不知道对不对[doge][doge][doge]
【回复】回复 @Fyniny : 严格来说确实可以细分,我目前的理解是像回调、设计模式这种抽象的概念只是一种编程的范式,而具体的事件机制是对他们的一种实现,由于很多零散知识是自己找的,很多地方只讲其一,做不到融会贯通,没看到他们之间的深刻联系
Himpq:
你妈叫你买菜,你直接甩给你妈菜摊老板的送货电话。

挂神也想恋爱:
个人感觉回调函数最大的用处是能省掉很多重复的if[笑哭]

【回复】回调的作用是可以完整实现异步,事件发布订阅监听
【回复】你要是搞图形的,看看openGL。里面全是回调。
【回复】回复 @Sybili :将函数指针赋值给变量 用一次if选择不同硬件驱动函数 在之后流程中无需反复使用if判断硬件类型 在Linux内核驱动里很常见的写法
叩舭丶布莱恩特:
整这么麻烦,说白了就是正常情况下我们调用函数是知道函数被实现了的,直接调用就行。而回调函数就是别人先调用,我们再去定义函数。 举个简单例子,调用函数就是引用名人名言,而回调函数就是你事先在作文里编纂名言,然后去柯洁直播间发sc让他念

真狂猎:
各种指针告诉我们,任何东西都能被我们想要的方式执行,只要你编码能力够强。 回调函数只是被解释器规范好,相对简单的一种函数的使用方式。 何必把大佬封装好的东西拿出来解读,该解读的应该是其底层实现,如果有必要。

CSbeta:
回调的本质就是被逻辑上的调用,回调翻译地太抽象,可能更直白的翻译应当为 被调函数

沉空木:
回调是函数作为参数,和指针没有半毛钱关系

老柯里:
你这个定义不准确 你直接说是函数地址给了函数指针变量 你有这个函数指针变量 就能随时读这个变量存的数据也就是函数地址 且能解引用这个地址 通过地址访问到函数的内存 然后直接使用这个函数不就好了

Hashable:
回调函数和Python的装饰器是不是有点相同的味道?

00helloworld00:
讲概念都大同小异,没什么区别。最重要的是为什么要用callback函数,他的使用场景是什么,什么时候要用什么时候不要用

jaykinga:
就是一个入口地址,给什么入口地址就跳到那里运行

moahu:
我感觉用Python讲比较好。Python里只说函数是一等对象。写Python很习惯的把函数当参数传。然后调用。根本不会给这取个名字(回调函数)专门学

科技 计算机 程序员 函数 知识 编程 代码 回调 回调函数

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!