回调
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgCallback
- 最后更新: 2021-07-08
回调过程
描述
来自维基百科:回调,也称为"call-after"函数,是任何作为参数传递给其他代码的可执行代码;该其他代码预期在给定时间回调(执行)该参数。这种执行可能是立即的,如同步(或阻塞)回调,也可能在稍后时间发生,如异步(或延迟)回调。
示例
以数学函数作为绘图函数调用参数的示例:
(调用通过调用 'PlotF()' 过程实现,回调函数是 'Linear()'、'Sinusoidal()' 或 'Quadratic()' 函数)
start GeSHi
vb
Type MathFunction As Function( ByVal x As Double ) As Double
Function Linear( ByVal x As Double ) As Double
Return x
End Function
Function Quadratic( ByVal x As Double ) As Double
Return x * x
End Function
Function Sinusoidal( ByVal x As Double ) As Double
Return Sin(x)
End Function
Sub PlotF( ByVal f As MathFunction )
PSet( -15, f(-15) )
For x As Double = -15 To 15 Step 0.1
Line -( x, f(x) )
Next
End Sub
Screen 19
Window (-15,-10)-(15,10)
PlotF( @Linear )
PlotF( @Sinusoidal )
PlotF( @Quadratic )
Sleepend GeSHi
三个回调过程是同步的,因为每个回调函数在 'PlotF()' 返回给调用代码之前都完全执行完毕。
类似的绘图示例(如上),但带有异步回调。这里添加了一个人为的延迟。一个更现实的场景是,如果要绘制的数据是从 web 服务器获取的,响应时间超过了程序主循环可接受的时间(防止阻塞行为):
start GeSHi
vb
#Include "fbthread.bi"
Type MathFunction As Function( ByVal x As Double ) As Double
Sub ThreadPlot( ByVal p As Any Ptr )
Sleep 1500, 1 '' sleep added only to check the asynchronous way of the callback
Dim f As MathFunction = p
Window (-15,-10)-(15,10)
PSet( -15, f(-15) )
For x As Double = -15 To 15 Step 0.1
Line -( x, f(x) )
Next
End Sub
Function PlotF( ByVal f As MathFunction ) As String
Print "Plotting requested"
Threaddetach( ThreadCreate( @ThreadPlot, f ) )
Return "Plotting request taken into account"
End Function
Function Linear( ByVal x As Double ) As Double
Return x
End Function
Function Quadratic( ByVal x As Double ) As Double
Return x * x
End Function
Function Sinusoidal( ByVal x As Double ) As Double
Return Sin(x)
End Function
Screen 19
Print PlotF( @Linear )
Print PlotF( @Sinusoidal )
Print PlotF( @Quadratic )
'' following code added only to check the asynchronous way of callbacks
Print "Main program continues ";
For I As Integer = 1 To 15
Print ".";
Sleep 200, 1
Next I
Print
Print "Main program finished"
Sleepend GeSHi
三个回调过程是异步的,因为 'PlotF()' 函数立即返回,而每个回调函数在 'PlotF()' 为每个回调函数创建的 'ThreadPlot()' 线程中与调用者的后续代码并行执行。
使用 qsort 算法对数组进行排序时比较值的回调函数示例:
(调用通过调用 'qsort()' 过程实现,回调函数是 'CmpVarLenStr()' 函数)
start GeSHi
vb
#include "crt/stdlib.bi"
Function CmpVarLenStr CDecl( ByVal p1 As Any Ptr, ByVal p2 As Any Ptr ) As Long '' compare 2 var-len strings
Dim As String Ptr ps1 = p1
Dim As String Ptr ps2 = p2
If *ps1 < *ps2 Then
Return -1
ElseIf *ps1 > *ps2 Then
Return 1
Else
Return 0
End If
End Function
Sub PrintList( array() As String) '' print a var-len string list
For I As Integer = LBound(array) To UBound(array)
Print array(I)
Next I
Print
End Sub
Dim forename(1 To 12) As String = {"Madison", "Emily", "Hailey", "Sarah", "Kaitlyn", "Hannah", _
"Jacob", "Christopher", "Nicholas", "Michael", "Matthew", "Joshua" }
Print "LIST OF UNSORTED FORENAMES:"
PrintList( forename() )
qsort( @forename(LBound(forename)), UBound(forename) - LBound(forename) + 1, SizeOf(String), @CmpVarLenStr )
Print "LIST OF SORTED FORENAMES:"
PrintList( forename() )
Sleepend GeSHi
回调过程是同步的,因为回调函数在 'qsort()' 返回给调用代码之前,被 'qsort()' 完整执行(多次)。
参见
返回 目录