何时使用回调函数?

11

在什么情况下使用回调函数?我知道它们的工作原理,我已经看到它们被使用并且自己也多次使用过。

C语言的一个例子是libcurl,它依赖于回调函数进行数据检索。

另一个相反的例子是OpenSSL:在我使用它的地方,我使用输出参数:

ret = somefunc(&target_value);
if(ret != 0)
    //error case

我想知道何时使用哪个?回调只在异步操作时有用吗?我正在设计我的应用程序API,我想知道是否使用回调还是仅使用输出参数。在内部,它将使用libcurl和OpenSSL作为主要构建库,并且“返回”的参数是OpenSSL数据类型。

我没有看到回调比直接返回有任何好处。如果我想以某种方式处理数据而不仅仅是返回数据,则这只有用处吗?但是然后我可以处理返回的数据,区别在哪里?

4个回答

9
在最简单的情况下,这两种方法是等价的。但是,如果回调可以被多次调用以在数据到达时处理数据,则回调方法提供了更大的灵活性,并且这种灵活性不仅限于异步使用情况。 libcurl是一个很好的例子:它提供了一个API,允许为所有新到达的数据指定回调。如你所提出的替代方案将只是“返回数据”。但是,如何返回?如果数据收集到内存缓冲区中,缓冲区可能会非常大,而调用者可能只想将其保存到文件中,例如下载器。如果将数据保存到返回给调用者的文件中,如果调用者实际上只想将其保存到内存中,例如显示图像的Web浏览器,那么它可能会产生不必要的IO。无论哪种方法都不是最佳选择,如果调用者想要在流式传输数据时处理数据,例如计算校验和,并且根本不需要将其存储。
回调方法允许调用者决定如何处理数据的各个块或将它们组装成更大的整体。

4
回调函数可用于异步通知。当您向某个API注册回调函数时,您预期该回调函数在发生某些事件时运行。类似地,您可以将它们用作数据处理管道中的中间步骤(如果您熟悉音频/录音行业,则类似于“插入”)。
因此,总结一下,这是我遇到和/或实现回调方案的两个主要范例:
1. 数据到达或发生某些事件时我会告诉您 - 您根据需要使用它。 2. 我会让您有机会在我处理它之前修改某些数据。

1
如果可以立即返回值,则不需要回调。正如您所推测的那样,在无法立即返回值的情况下(可能是长时间运行的操作最好异步执行),回调非常有用。

0

我的看法是:我认为这取决于哪个模块需要知道哪个模块?我们称它们为数据用户和IO。 假设您有一些IO,其中数据进入。 IO模块甚至可能不知道谁对数据感兴趣。但是,数据用户确切地知道它需要哪些数据。因此,IO应该提供一个类似于subscribe_to_incoming_data(func)的函数,而数据用户模块将订阅IO模块具有的特定数据。另一种选择是更改IO模块中的代码以调用数据用户。但是,使用现有库,您绝对不想触及其他人为您提供的现有代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接