Include Example

Input:

I am a.
route execute finish.
I am b.
route execute finish.

What is Callback

Callback function define:

If a function is threated as a function parameter, then the function named a Callback function.

Callback function is a very common progrmm design pattrn.

Callback function is a overall process, with at least three parts working together.

Three parts is :

  1. Futurer
  2. Router
  3. Predefine function

Sequence Diagram:

The ConnectorMan( )as like a router, You can send that A( ) function name or B( ) function name,even anything function name. Router function recived the function name and go to call it.

function extends:

Callback function can is a Predefine function,too can isAnonymous functions(Closures) or Lambda.

Functional induction:

  • Unknown things:

    • 回调函数其实是一个程序在设计之初,设计者需要考虑未来出现未知情况的一种解决方案。
    • 在解方程应用里,如果有未知数的话,可以先将未知数设为X,这样也不影响列方程,解方程等后续过程,而Callback就类似这个未知数x.
  • Agility and Smart:

    • 将使用者的角色转换为一个订阅者,而不是一个全职看门人。
    • 如果比喻成数学函数来看待,数学函数需要由使用者传递过来因变量,而Callback比函数范围更扩大了,直接设整个执行函数设为一个因变量

The difference between Callback function and Event function

很多编程语言、系统、工具、框架都会事先定义好一些事件函数,比如JS的点击事件、页面加载事件...

事件函数有点类似上面提到的route function,只不过这个事件函数一般不能由使用者创建,是系统最初就设定好了,使用者只需要编写事件响应时需要做什么即可。

回调函数事件函数都是在某些特定条件下被调用的函数。但是,它们之间有一些区别:

  • 回调函数是由另一个函数调用的,而事件函数是由操作系统或硬件调用的;
  • 回调函数通常用于执行一些特定的任务,而事件函数通常用于响应某些事件;
  • 回调函数可以由用户定义,而事件函数通常是内置的;
  • 回调函数事件函数都是非常重要的编程技术。它们在各种各样的场景中都有应用。

Understanding callbacks from an assembly language perspective

在汇编语言中,程序的执行是按照线性顺序的,从一个指令到下一个指令。然而,回调允许我们在程序执行期间将控制权传递给另一个函数(回调函数),并在回调函数执行完毕后返回到原始函数继续执行。这种传递控制权的方式称为回调。

常见的回调模式是事件驱动编程,其中程序等待事件的发生,然后调用相应的回调函数来处理事件。在汇编语言中,这可以通过轮询或中断来实现。

回调函数在汇编语言中,可以通过使用 CALL指令来实现。CALL指令将当前函数的执行状态(包括程序计数器堆栈指针)保存到堆栈中,然后跳转到指定的函数地址。 当指定的函数执行完毕后,将返回到调用它的函数。

下面是一个使用 CALL指令 实现回调函数的汇编语言程序:

main:
mov ebx, 10
mov ecx, 20
call sum
mov eax, ebx
ret sum:
mov eax, ebx
add eax, ecx
ret

Input:

上面的汇编代码运行后的结果是 30。
main 函数将 10 和 20 作为参数传递给 sum 函数。sum 函数将这两个参数相加,得到 30。然后,sum 函数将 30 作为返回值返回给 main 函数。main 函数将 30 保存到 eax 寄存器中,然后返回。

在这个程序中,main函数 调用 sum函数。sum函数将两个参数相加,然后将结果返回给 main 函数。

当 sum 函数执行完毕后,将返回到 main 函数。main 函数将 sum 函数的返回值保存到 eax 寄存器中,然后返回。

通过使用 CALL 指令,我们可以实现在一个函数中调用另一个函数。这种技术在编写汇编语言程序时非常有用。

总结:

回调函数看起来像一个函数调用另一个函数然后返回,但实际上它全部是通过程序地址的传递跳转指令来实现控制流的切换

Example - 在恰当的时机发出通知

以一个定时认为举例,需求是你需要制作一个每天早上7点钟播放音乐的程序。

一个笨办法:

  1. 先写好播放音乐程序;
  2. 再写一个循环,定时去获取系统时间,如果获取的时间是早上7点,就去执行写好的播放音乐程序。

确实能实现,但是不如下面的方式优雅:

  1. 先写好播放音乐程序;
  2. 创建一个新线程,线程里面有一个函数可以接纳回调函数,只需要填入两个参数,一个是时间,二是播放音乐函数名;
  3. 启动线程,只要时间到了之后,就自动去执行播放音乐程序。

Example - 让现代的使用者去解决现代的未知

以一个排序函数举例,假设你要排序下面这些学号:

'20211001', '20212007', '20212003', '20212002', '20211004', '20212001'

2021 - 入学年份

0、1 - 性别

001 - 班级

将班级做升序排序。

当你要设计这个排序函数的时候,你只能写一个大体固定的流程,因为你无法知道未来的调用者想要排序那部分,用什么杨的排序方式,当需要应对未知情况的时候,使用回调就能很好解决。



Input:

['20211001', '20212001', '20212002', '20212003', '20211004', '20212007']

Example - 提高运行效率

假设你作为Windows系统的开发人员,你了解到用户有获取Windows系统里某个活动窗口的ID信息,当前系统有成千上万个窗口,你要怎么设计一个对外提供使用的函数?还得尽量高效率?

一种笨方法:

  1. 直接将成千上万个窗口信息直接返回给用户,让用户自己查找出他想要的信息。

也算是完成了需求,不过不够高效率,也不是很贴合用户需求,用户只是想要一个指定的窗口信息而已。

更高效的方式:

  1. 对外提供一个窗口枚举函数,该函数的参数是一个函数名(回调函数);
  2. 用户只需要在回调函数内定义好匹配的方式,需要约定好,回调函数的返回值是一个boolea, 匹配上就返回False-0, 没匹配上就返回True-1,如果枚举函数收到True值,则继续向下枚举下一个窗口。

这样做的好处是,如果运气好,枚举函数在前几个窗口就找到用户想要的,按照约定返回False, 则枚举终止。

下面以一个Win API举例说明:

EnumWindows函数是Windows编程中用于枚举所有顶层窗口的API函数。它允许你传递一个函数指针,然后依次调用此函数来处理所有顶层窗口。

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

参数:

  • lpEnumFunc:指向一个应用程序定义的回调函数的指针。系统会为每个顶层窗口调用此回调函数,直到函数返回0,或者所有的顶层窗口都已枚举。如果回调函数返回0,枚举函数将停止,否则,枚举函数将继续。这个函数的原型必须与WNDENUMPROC实例一样。
  • lParam:指定传递给回调函数的应用程序定义的值。

返回值:

  • 如果函数成功,返回值为非零。如果函数失败,返回值为零。

让我们来看一个EnumWindows的使用案例,它枚举所有的顶层窗口,并打印窗口标题:

#include <windows.h>
#include <stdio.h> BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char class_name[80];
char title[80];
GetClassName(hwnd, class_name, sizeof(class_name));
GetWindowText(hwnd, title, sizeof(title));
printf("Window title: %s\n", title);
printf("Window class: %s\n", class_name);
return TRUE;
} int main()
{
EnumWindows(EnumWindowsProc, NULL);
return 0;
}

这段代码先定义了一个回调函数EnumWindowsProc,对每个顶层窗口获取窗口的类名和标题,然后打印出来。然后在main函数中调用EnumWindows,传递EnumWindowsProc作为回调函数。

Advanced Questions

  • 回调地域
  • 向回调函数传入参数
  • 获取回调函数的返回值
  • 同步回调函数
  • 异步回调函数
  • ...

Data Archiving

https://sequencediagram.org/

title This is a Callback sequence

note over Futurer : Futurer do custom
Futurer->ConnectorMan( ):function A( )
activate ConnectorMan( ) #red ConnectorMan( ) -> function A( ): To Call A( )
activate function A( ) #blue
function A( ) -> function A( ): Execute the function
function A( )-->ConnectorMan( ):return
deactivate function A( ) ConnectorMan( )-->Futurer:return
deactivate ConnectorMan( ) participant function B( )
participant function Anything( )

Callback Function Essence的更多相关文章

  1. 理解callback function in javascript

    以下内容主要摘自[1,2] (1)In javascript, functions are first-class objects, which means functions can be used ...

  2. C语言中的回调函数(Callback Function)

    1 定义和使用场合 回调函数是指 使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数.函数是你实现 ...

  3. (C/C++) Callback Function 回调(diao)函数

    原文: http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557/Callback-Functions-Tutorial ...

  4. callback function(回调函数) - 术语

    回调函数(CallBack Function)的定义: [todo] 下面是callback的一个场景,linux内核.LwIP里也有使用callback funcs.

  5. JavaScript callback function 回调函数的理解

    来源于:http://mao.li/javascript/javascript-callback-function/ 看到segmentfault上的这个问题 JavaScript 回调函数怎么理解, ...

  6. JS之Callback function(回调函数)

    JS中的回调函数: 1.概念: 函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b,那么这个过程就叫回调,即把函数作为参数传入到另一个函数中,这个函数就是所谓的回调函数. 2.举例: ...

  7. JavaScript callback function 理解

    看到segmentfault上的这个问题 JavaScript 回调函数怎么理解,觉得大家把异步和回调的概念混淆在一起了.做了回答: 我觉得大家有点把回调(callback)和异步(asynchron ...

  8. Node.js学习 - CallBack Function

    Node.js异步编程的直接体现就是回调,Node使用了大量的回调函数,其所有的API都支持回调. 阻塞代码实例(同步) var fs = require("fs"); var d ...

  9. ob_gzhandler — ob_start callback function to gzip output buffer

    <?php ob_start("ob_gzhandler"); ?><html><body><p>This should be a  ...

  10. [Unit Testing] Unit Test a Function that Invokes a Callback with a Sinon Spy

    Unit testing functions that invoke callbacks can require a lot of setup code. Using sinon.spy to cre ...

随机推荐

  1. 2022-07-26:以下go语言代码输出什么?A:5;B:hello;C:编译错误;D:运行错误。 package main import ( “fmt“ ) type integer in

    2022-07-26:以下go语言代码输出什么?A:5:B:hello:C:编译错误:D:运行错误. package main import ( "fmt" ) type inte ...

  2. 2022-05-22:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p

    2022-05-22:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个节点 p.q,最近公共祖先表示为一个节点 x,满足 x ...

  3. 2022-03-22:二进制取反。 有一个二进制字符串,可以选择该串中的任意一段区间进行取反(可以进行一次或不进行),取反指将0变为1,将1变为0。那么取反之后的num可能的最大的字典序是多少呢。如有

    2022-03-22:二进制取反. 有一个二进制字符串,可以选择该串中的任意一段区间进行取反(可以进行一次或不进行),取反指将0变为1,将1变为0.那么取反之后的num可能的最大的字典序是多少呢.如有 ...

  4. vue全家桶进阶之路14:常用属性和方法

    Vue2中常用的属性和方法: 属性 el:用于指定Vue实例挂载的元素,可以是CSS选择器.HTML元素或Vue组件. data:用于存储Vue实例的响应式数据,也可以是一个函数,返回一个对象,用于提 ...

  5. 禁用input自动补全,模拟type=password输入字符显示为星号

    最近遇到一个想禁用浏览器的密码自动补全的功能,翻遍了整个技术论坛大多使用用auto-complete="new-password"但是本人测试不怎么管用,所有又找到了如下几种方法, ...

  6. nginx发布vue 项目

    在本次使用nginx发布vue项目遇到 配置location 始终404 和 在项目子目录点击浏览器刷新出现404问题 使用nginx发布vue项目,为了方便测试就下载了一个nginx 放置自己目录下 ...

  7. OneForAll下载安装以及环境配置

    python-3.9.7-amd64 OneForAll-master python安装以及插件安装 首先下载python解压到电脑c盘在c盘中创建一个工具文件夹,然后下载OneForAll-mast ...

  8. 【Azure K8S】AKS升级 Kubernetes version 失败问题的分析与解决

    问题描述 创建Azure Kubernetes Service服务后,需要升级AKS集群的 kubernetes version.在AKS页面的 Cluster configuration 页面中,选 ...

  9. Windows操作系统中常用的Dos命令

    打开CMD的方式: Win+R 输入cmd打开控制台(推荐使用) 在任意文件夹下,按住shift键,点击鼠标右键,选择在此处打开命令行窗口 在资源管理器的地址栏路径前面加上cmd+空格: 常用的Dos ...

  10. 自然语言处理(NLP) - 前预训练时代的自监督学习

    前预训练时代的自监督学习自回归.自编码预训练的前世 神经网络(Neural Network, NN) 损失函数,度量神经网络的预测结果和真实结果相差多少 平方差损失(欧式距离角度)预测概率分部和实际标 ...