Go并发编程实战
上QQ阅读APP看书,第一时间看更新

3.7 回调函数

在JavaScript中实现异步的Ajax请求时基本都要用回调函数。由于异步请求何时返回是不确定的,因此不适用于同步方法,否则可能会阻塞UI线程。当请求执行完成后,再调用回调函数,这样的用户体验会更好,执行效率也更高。

Go语言当然也支持回调函数(Callback Function)。回调函数本质上就是作为另一个函数参数的函数。在函数体中,可以在适当的时机调用参数对应的函数,形成回调。在很多语言的内部,也会大量使用回调函数,比如事件机制。下面是演示Go语言中函数回调基本用法的示例程序3-10。

示例程序3-10 回调函数的基本用法:chapter03\code09\func.go

在示例程序3-10中,第03行用关键字type定义了一个callback类型。这个callback类型是一个函数,签名为func(int, int) int。因此,callback这个类型的变量只能接收签名为func(int, int) int格式的函数。第04行定义了一个函数doAdd,它接收3个参数,前2个为整数类型,第3个为callback类型。第06行用return f(a, b)语句调用传入的f函数并返回该函数的计算结果。

第08~11行定义了一个add函数,他的函数签名和callback类型一致,这样add函数就可以作为doAdd函数的第3个参数了,如第14行的语句doAdd(a, b, add)所示。当然,还可以直接给出回调函数的定义,如第15~18行所示。

函数回调其实非常有用,下面给出一段模拟事件机制的示例程序。由于目前尚未介绍数组和结构体struct等概念,因此先给出相对松散的事件类型定义,如示例程序3-11所示。

示例程序3-11 回调模拟事件处理:chapter03\code09\func2.go

在示例程序3-11中,首先用type声明了3个用于回调的函数类型,分别来模拟Sum操作前的事件、Sum操作的事件和Sum操作后的事件。回调函数的具体实现是通过注册函数RegEvent来实现事件绑定,StartSum函数中则确定了3个回调函数的运行顺序。用go run func2.go命令来运行这个示例程序,结果如下:

====SumBeforeEvent====
====SumEvent====
====SumEndEvent====
End
11