10

什么时候使用回调函数?我知道它们是如何工作的,我已经看到它们在使用中,而且我自己也使用过很多次。

C 世界的一个例子是libcurl它依赖于回调来检索数据。

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

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

我想知道什么时候使用哪个?回调仅对异步内容有用吗?我目前正在设计我的应用程序的 API,我想知道是使用回调还是只使用 out 参数。在底层,它将使用 libcurl 和 OpenSSL 作为它构建的主要库,并且参数“returned”是 OpenSSL 数据类型。

我看不出回调比仅仅返回有什么好处。如果我想以任何方式处理数据而不是仅仅将其返回,这是否才有用?但是我可以处理返回的数据。区别在哪里?

4

4 回答 4

8

在最简单的情况下,这两种方法是等价的。但是如果回调可以在数据到达时被多次调用来处理数据,那么回调方法提供了更大的灵活性,并且这种灵活性不仅限于异步用例。

libcurl 就是一个很好的例子:它提供了一个 API,允许为所有新到达的数据指定回调。正如您所介绍的那样,另一种选择是只返回 data。但归还——如何?如果将数据收集到内存缓冲区中,则缓冲区最终可能会非常大,调用者可能只想将其保存到文件中,例如下载程序。如果数据被保存到一个文件名返回给调用者,如果调用者实际上只是想将它存储在内存中,它可能会产生不必要的 IO,就像显示图像的 web 浏览器一样。如果调用者想要在数据流时处理数据,比如计算校验和,并且根本不需要存储它,那么这两种方法都是次优的。

回调方法允许调用者决定如何处理单个数据块或将其组装成一个更大的整体。

于 2013-04-14T21:58:01.750 回答
4

回调对于异步通知很有用。当您使用某些 API 注册回调时,您希望该回调在某些事件发生时运行。同样,您可以将它们用作数据处理管道中的中间步骤(如果您熟悉音频/录音行业,则类似于“插入”)。

因此,总而言之,这是我遇到和/或实现的回调方案的两个主要范例:

  1. 当数据到达或某些事件发生时,我会告诉你——你可以随意使用它。
  2. 在我处理它之前,我会给你修改一些数据的机会。
于 2013-04-14T21:56:45.040 回答
1

如果可以立即返回值,那么可以,不需要回调。正如您所推测的,回调在由于某种原因无法立即返回值的情况下很有用(也许它只是一个长时间运行的操作,最好异步执行)。

于 2013-04-14T21:55:14.043 回答
0

我对此的看法:我认为哪个模块必须知道哪个模块?我们称它们为数据用户和 IO。假设你有一些 IO,数据从那里进来。IO-Module 甚至可能不知道谁对数据感兴趣。然而,数据用户确切地知道它需要哪些数据。所以 IO 应该提供一个类似 subscribe_to_incoming_data(func) 的函数,Data-User 模块将订阅 IO-Module 拥有的特定数据。另一种方法是更改​​ IO-Module 中的代码以调用 Data-User。但是对于现有的库,您绝对不想触及其他人提供给您的现有代码。

于 2021-08-22T00:10:53.493 回答