为什么要用回调函数? [问题点数:20分,结帖人wxf041041]点击打开链接

  • 不显示删除回复
  • 显示所有回复
  • 显示星级回复
  • 显示得分回复
  • 只显示楼主
  • 收藏
wxf041041
wxf041041
等级:
结帖率:100%
楼主发表于: 2012-06-04 18:36:18
  首先我知道回调函数是怎么用的,也知道是自已定义注册,系统调用,但是我不知道为什么要用回调函数? 这样用的好处是什么·

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理

回复次数:17

jackyjkchen
jackyjkchen
等级:

4
2
4
#1 得分:0回复于: 2012-06-04 18:39:48
回调函数和一般的指针传递其实没什么区别,你想让strcpy拷贝你指定的字符串,那就传个字符传指针;如果你想让某个函数执行你自定义的函数,就传函数指针……

回调函数,是应付某一类需求最自然的方法,你为什么不问“为什么strcpy要穿个char*?为什么不换种方法呢?”

【社区之星】朱燚:转战传统应用的弄潮儿
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理

jackyjkchen
jackyjkchen
等级:

4
2
4
#2 得分:20回复于: 2012-06-04 18:41:44
更高级的语言中,回调函数的形式会发生一些变化,C++中有回调类,C#有委托

但是本质上都是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的

CSDN投诉事项说明
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理

dr8737010
dr8737010
等级:
#3 得分:0回复于: 2012-06-05 09:30:33
主要还是方便应用程序的开发吧,有点像考试填空的感觉,一般api的提供者做好了大部分必要的工作,剩下需要程序员自己写的代码就是具体应用所需要的代码,举个例子,假设操作系统(或者某框架)提供了执行程序的方法:
void execute(){
  init(); //初始化必要的资源
  dosomething(); //由程序员自己填写的代码,即回调函数
  destory(); //释放使用到的资源
}
其中第一步和第三步已经实现了,需要程序员根据实际的情况来填写第二步到底要做什么事情,这就是回调函数的典型应用场景.
在高级语言中,回调函数也就是观察者模式的一种应用.
【社区问答】曾宪杰:大型网站系统与Java中间件
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理

ouyh12345
ouyh12345
等级:

2
#4 得分:0回复于: 2012-06-05 09:35:26
在异步的情况下,让其它模块调用本模块的某方法
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
csucdl
csucdl
等级:
#5 得分:0回复于: 2012-06-05 09:51:31
可以解耦
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
delete2009
delete2009
等级:
#6 得分:0回复于: 2012-08-01 18:35:10
为什么要用回调函数?举例如下
你饿了,想吃饭,就一会去问你妈一声"开饭没有啊?"这就正常函数调用.
但是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.于是你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说"开饭啦,快回来吃饭吧!"
其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动作.你妈打电话叫你,就是个回调过程.
转自:http://hi.baidu.com/%CE%E2_%F0%A9/blog/item/eec507cf7e72d20f92457eb2.html
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
pathuang68
pathuang68
等级:

2
#7 得分:0回复于: 2012-08-01 20:34:16
引用 6 楼  的回复:

为什么要用回调函数?举例如下
你饿了,想吃饭,就一会去问你妈一声"开饭没有啊?"这就正常函数调用.
但是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.于是你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说"开饭啦,快回来吃饭吧!"
其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动作.你妈打电话叫你,就是个回调过程.
转自:http://hi.……

++
这个很形象:)

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
wuxunfeng
wudywind
等级:
#8 得分:0回复于: 2012-11-07 15:32:33
引用 7 楼 pathuang68 的回复:

引用 6 楼  的回复:为什么要用回调函数?举例如下
你饿了,想吃饭,就一会去问你妈一声"开饭没有啊?"这就正常函数调用.
但是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.于是你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说"开饭啦,快回来吃饭吧!"
其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动作.你妈打电话叫你……

这只是回调函数应用的一个例子和场景,不能说这就是回调函数了。二楼说道本质了
本质上都是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
wuxunfeng
wudywind
等级:
#9 得分:0回复于: 2012-11-07 15:34:04
不是很理解回调函数,直观来看,是不是就是函数的参数由函数指针,调用者可以给函数指定函数,在内部被调用。
    为什么回调函数一定要是异步的呢?
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
wuxunfeng
wudywind
等级:
#10 得分:0回复于: 2012-11-07 15:34:37
引用 6 楼 delete2009 的回复:

为什么要用回调函数?举例如下
你饿了,想吃饭,就一会去问你妈一声"开饭没有啊?"这就正常函数调用.
但是今天你妈包饺子,花的时间比较长,你跑啊跑啊,就烦了.于是你给你妈说,我先出去玩会,开饭的时候打我手机.等过了一阵,你妈给你打电话说"开饭啦,快回来吃饭吧!"
其中,你告诉你妈打手机找你,就是个你把回调函数句柄保存到你妈的动作.你妈打电话叫你,就是个回调过程.
转……

这是一个异步机制吧

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
Saleayas
Saleayas
等级:
#11 得分:0回复于: 2012-11-07 15:59:37
那就表示你现在不需要用到回调函数。
等待你需要这个的时候,你会发现,原来回调函数这么友善。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
max_min_ 
max_min_
等级:

5
4
#12 得分:0回复于: 2012-11-07 16:28:22
引用 2 楼 jackyjkchen 的回复:

更高级的语言中,回调函数的形式会发生一些变化,C++中有回调类,C#有委托

但是本质上都是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的

如果只是想让别人的代码执行自己的代码,那为什么不直接在别人的代码调用自己的代码呢?

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
wuxunfeng
wudywind
等级:
#13 得分:0回复于: 2012-11-19 10:24:19
引用 12 楼 max_min_ 的回复:

引用 2 楼 jackyjkchen 的回复:更高级的语言中,回调函数的形式会发生一些变化,C++中有回调类,C#有委托

但是本质上都是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的

如果只是想让别人的代码执行自己的代码,那为什么不直接在别人的代码调用自己的代码呢?

因为"而别人的代码你又不能动",就是说别人给你提供他封装的调用,你不能去改动代码,所以提供一个回调的参数

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
jiangwei19900106
jiangwei19900106
等级:
#14 得分:0回复于: 2012-11-19 12:02:22
引用 5 楼 csucdl 的回复:

可以解耦

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
baichi4141
baichi4141
等级:
#15 得分:0回复于: 2012-11-19 12:10:00
引用 12 楼 max_min_ 的回复:

引用 2 楼 jackyjkchen 的回复:更高级的语言中,回调函数的形式会发生一些变化,C++中有回调类,C#有委托

但是本质上都是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的

如果只是想让别人的代码执行自己的代码,那为什么不直接在别人的代码调用自己的代码呢?

别人给你的不是源代码,是一个已经编译好的模块,并且不会给你源代码,那是商业机密
留给你一个接口,你把你要执行的代码以回调函数的形式交给这个接口,由别人编写的模块在需要的时候调用

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
TNT_snowball
TNT_snowball
等级:
#16 得分:0回复于: 2014-01-07 18:30:49
我们为什么要用回调函数呢?
记得在一次C++开发面试的时候被被一位主面官问到过这个问题,现在再回答一遍。

我们对回调函数的使用无非是对函数指针的应用,函数指针的概念本身很简单,但是把函数指针应用于回调函数就体现了一种解决问题的策略,一种设计系统的思想。
在解释这种思想前我想先说明一下,回调函数固然能解决一部分系统架构问题但是绝不能再系统内到处都是,如果你发现你的系统内到处都是回调函数,那么你一定要重构你的系统。回调函数本身是一种破坏系统结构的设计思路,回调函数会绝对的变化系统的运行轨迹,执行顺序,调用顺序。回调函数的出现会让读到你的代码的人非常的懵头转向。

那么什么是回调函数呢,那是不得以而为之的设计策略,想象一种系统实现:在一个下载系统中有一个文件下载模块和一个下载文件当前进度显示模块,系统要求实时的显示文件的下载进度,想想很简单在面向对象的世界里无非是实现两个类而已。但是问题恰恰出在这里,显示模块如何驱动下载进度条?显示模块不知道也不应该知道下载模块所知道的文件下载进度(面向对象设计的封装性,模块间要解耦,模块内要内聚),文件下载进度是只有下载模块才知道的事情,解决方案很简单给下载模块传递一个函数指针作为回调函数驱动显示模块的显示进度。

在面向对象的世界中这样的例子还真不少,造成这样的问题的根源,相信大家已经从上面的叙述中体会到了,就是面向对象的程序设计思想,就是设计模式中要求的模块独立性,高内聚低耦合等特性。

封装变化的编程策略给编程人员第一位的指导思想就是面向接口编程米,即设计模式中提到的面向虚拟编程而不是面向实现。这样的编程思想极大地革新了编程世界,可以说没有这一原则就没有面向对象的程序设计,这一原则给程序设计一种指导思想即如何更高的将现实模型映射成程序模型。这样的设计思想在极大地催生高度独立性模块的同时削弱了模块间的协作性,也就是耦合性,它使得模块间更多的从事着单向的调用工作,一个模块需要某种服务就去找另一个模块,这使得程序呈现出层次性,高层通过接口调用底层,底层提供服务。但是现实世界中严格遵循现层次特性的系统是很少见的,绝对的MVC是不存在的,因为更多的模块要求通并协作,可见没有耦合就没有协作没有好的调用关系,耦合真的不是错。

既然我们需要模块间的协作,同时我们又厌恶的摒弃模块间你中有我我中有你的暧昧关系那如何生成系统呢,答案是函数指针(不一定一定是函数指针)也就是使用回调的方式。如果一个对象关心另一个对象的状态变化那么给状态的变化注册回调函数让它通知你这类状态的改变,这样在封装了模块变化的同时实现了模块间的协作关系另辟独径的给对象解耦。

对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理
zlhxiaohui
zhenglianghui
等级:
#17 得分:0回复于: 2014-03-08 21:53:55
引用 16 楼 TNT_snowball 的回复:

我们为什么要用回调函数呢?
记得在一次C++开发面试的时候被被一位主面官问到过这个问题,现在再回答一遍。

我们对回调函数的使用无非是对函数指针的应用,函数指针的概念本身很简单,但是把函数指针应用于回调函数就体现了一种解决问题的策略,一种设计系统的思想。
在解释这种思想前我想先说明一下,回调函数固然能解决一部分系统架构问题但是绝不能再系统内到处都是,如果你发现你的系统内到处都是回调函数,那么你一定要重构你的系统。回调函数本身是一种破坏系统结构的设计思路,回调函数会绝对的变化系统的运行轨迹,执行顺序,调用顺序。回调函数的出现会让读到你的代码的人非常的懵头转向。

那么什么是回调函数呢,那是不得以而为之的设计策略,想象一种系统实现:在一个下载系统中有一个文件下载模块和一个下载文件当前进度显示模块,系统要求实时的显示文件的下载进度,想想很简单在面向对象的世界里无非是实现两个类而已。但是问题恰恰出在这里,显示模块如何驱动下载进度条?显示模块不知道也不应该知道下载模块所知道的文件下载进度(面向对象设计的封装性,模块间要解耦,模块内要内聚),文件下载进度是只有下载模块才知道的事情,解决方案很简单给下载模块传递一个函数指针作为回调函数驱动显示模块的显示进度。

在面向对象的世界中这样的例子还真不少,造成这样的问题的根源,相信大家已经从上面的叙述中体会到了,就是面向对象的程序设计思想,就是设计模式中要求的模块独立性,高内聚低耦合等特性。

封装变化的编程策略给编程人员第一位的指导思想就是面向接口编程米,即设计模式中提到的面向虚拟编程而不是面向实现。这样的编程思想极大地革新了编程世界,可以说没有这一原则就没有面向对象的程序设计,这一原则给程序设计一种指导思想即如何更高的将现实模型映射成程序模型。这样的设计思想在极大地催生高度独立性模块的同时削弱了模块间的协作性,也就是耦合性,它使得模块间更多的从事着单向的调用工作,一个模块需要某种服务就去找另一个模块,这使得程序呈现出层次性,高层通过接口调用底层,底层提供服务。但是现实世界中严格遵循现层次特性的系统是很少见的,绝对的MVC是不存在的,因为更多的模块要求通并协作,可见没有耦合就没有协作没有好的调用关系,耦合真的不是错。

既然我们需要模块间的协作,同时我们又厌恶的摒弃模块间你中有我我中有你的暧昧关系那如何生成系统呢,答案是函数指针(不一定一定是函数指针)也就是使用回调的方式。如果一个对象关心另一个对象的状态变化那么给状态的变化注册回调函数让它通知你这类状态的改变,这样在封装了模块变化的同时实现了模块间的协作关系另辟独径的给对象解耦。

这个解释的很是到位,解释的蛮清楚!

为什么要用回调函数?相关推荐

  1. Go 学习笔记(16)— 函数(02)[函数签名、有名函数、匿名函数、调用匿名函数、匿名函数赋值给变量、匿名函数做回调函数]

    1. 函数签名 函数类型也叫做函数签名,可以使用 fmt.Printf("%T") 格式化参数打印函数类型. package mainimport "fmt"f ...

  2. OpenCV(六)形态学操作1--基础:膨胀与腐蚀(回调函数)

    目录 形态学通用API:morphologyEx 一.基础理论 1.邻接关系 (1)四邻接: (2)D邻接: (3) 八邻接: 2.连通性 (1)四连通: (2)八连通: (3)m连通: 3.形态学基 ...

  3. 函数指针--Nginx和Redis中两种回调函数写法

    1.Nginx和Redis中两种回调函数写法 #include <stdio.h>//仿Nginx风格 //结构外声明函数指针类型 typedef void (*ngx_connectio ...

  4. 回调函数在C/C++中的使用

    回调函数就是一个通过函数指针调用的函数.假如把A函数的指针当作参数传给B函数,然后在B函数中通过A函数传进来的这个指针调用A函数,那么就是回调机制.A函数就是回调函数,而通常情况下,A函数是在系统符合 ...

  5. 【FFmpeg】自定义回调函数处理AVIOContext中的数据

    1.简述 AVIOContext是FFmpeg管理输入输出数据的结构体,它的成员变量有指向数据的指针.大小以及处理数据的回调函数指针等等.如果使用avio_open或avio_open2来创建,它会根 ...

  6. php 回调递归,PHP数组函数 array_walk_recursive (使用回调函数递归遍历数组元素)

    在PHP中,数组函数 array_walk_recursive () 使用回调函数递归遍历数组元素. 函数语法:array_walk_recursive ( array &$array , c ...

  7. ajax post的回调函数另一个方法,jQueryajax–post()方法 - 米扑博客

    jQuery ajax - post() 实例 请求 test.php 网页,忽略返回值: $.post("test.php"); 通过 AJAX POST 请求改变 div 元素 ...

  8. nodejs回调函数理解

    回调实例 问题:想要得到一秒后 计算出的结果 //错误写法function add(x,y) {console.log(1);setTimeout(function () {console.log(2 ...

  9. dispatch callback ant design pro 网络请求回调函数

    index.jsx 代码解析:在组件初次渲染时调用 model 中 命名空间为  a_models  的 getData 网络请求,传了一个patload 参数和 callback 回调函数过去,然后 ...

  10. js回调函数和函数带参数的使用示例

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. //demo1 <html><head><meta charset=" ...

最新文章

  1. Electron Cash发布功能机BCH钱包,低端市场利好来袭
  2. oracle查询表的索引
  3. jtag和swd的区别
  4. 主板怎么开启csm_华擎Z490主板移植AMD SAM加速技术:游戏性能提升最多11.5%
  5. 有参组装新转录本cufflinks_转录本组装软件StringTie的使用说明
  6. [转]你所不知的 CSS ::before 和 ::after 伪元素用法
  7. leetcode 593. Valid Square | 593. 有效的正方形(Java)
  8. tolua++ 手册翻译地址
  9. java 创建定时器_SpringBoot创建定时任务
  10. Windows Terminal 完全配置教程(主题以及启动设置)
  11. python 监控内存_使用python写一个监控不同机器的使用内存情况并使用flask出图
  12. js事件流 事件捕获 及时间冒泡详解
  13. python安装后怎样配解释器_各个系统下的Python解释器相关安装方法
  14. 解决Hbuliderx的代码不能自动补全的问题
  15. 阿里巴巴优酷视频增强和超分辨率挑战赛-持续更新
  16. Unix网络编程开篇
  17. u深度重装系统详细教程_U盘怎样使用U深度给电脑装系统教程
  18. 中兴B860AV2.1-T_3.0_s905l3-b_uwe5621_线刷固件(附短接点示意图)
  19. STM32F429与CC2530 ZigBee模块通信
  20. 手动写一个搜索引擎(超详细)

热门文章

  1. 浅谈软件编程中的8大数据结构
  2. 【随机过程】第二章——随机过程概论
  3. sql server基础语句大全
  4. 【2022最新Java面试宝典】—— Java并发编程面试题(123道含答案)
  5. 开发一个微信小程序,对酒店经营管理有哪些好处?
  6. python数据分析案例(四):共享单车租用分析
  7. 参与影片《大城小事》的记者会
  8. c语言Dvv实验报告,电渗实验报告
  9. 在 Mac 上使用多点触控手势
  10. hackertyper