“回调”(callback)是一个在很多领域都频繁出现的概念:线程池、异步编程、操作系统、UI开发、网络通信等都离不开它。它不是某种技术,而是一种程序设计思想。
一句话理解
回调就是你把“干某件事的函数”交给别人(系统、框架、线程池),等这件事该发生的时候,它来“回过头来调用”你提供的函数。
你只是把“要做什么”告诉它,具体“什么时候做”和“怎么调用”是由别人来控制的。
再形象一点的理解
回调函数=做出一碟美味佳肴的秘方
你把秘方交给某厨师,你就不用管了
厨师根据他自己时间、场地的安排来做出这碟佳肴
等他做好后会把佳肴送到你餐桌上
程序中常见的回调场景
1. 线程池中的回调
你把任务提交给线程池:
executor.submit(() -> {
// 这个就是回调函数 —— 线程池空了以后就会来执行这个代码
System.out.println("任务执行");
});
你只是告诉线程池“有这么一个任务”,它什么时候调度、哪个线程来执行,你不控制。
2. 异步IO中的回调
比如网络请求、磁盘读写:
fs.readFile('a.txt', function(err, data) {
// 文件读取完成后,系统自动“回调”这段函数
console.log(data);
});
你注册一个函数,告诉系统“读完了文件就来调用我”。
3. 操作系统中的中断/信号处理
比如 C 语言中设置信号处理器:
signal(SIGINT, my_handler); // 回调函数 my_handler
当操作系统收到 Ctrl+C 中断时,就会回调你定义的 my_handler
函数。
4. 事件驱动模型中的回调
UI框架或JavaScript中监听按钮点击:
button.onclick = function() {
alert("点击了按钮"); // 回调
};
你只是注册了回调,点击事件何时发生你并不知道,但是发生时浏览器就来调用你这个函数。
回调的两个核心点
-
你传递的是一个函数(或函数引用)
-
你自己不主动调用它,是别人来调用你
回调的两种形式
类型 | 例子 | 控制权 |
---|---|---|
同步回调 | 数组排序传入比较函数 | 回调在你调用方法时立即执行 |
异步回调 | 线程池任务、事件触发 | 回调在未来某个时间点由系统执行 |