钩子和回调有什么区别?

时间:2012-06-18 16:57:55

标签: callback hook

通过阅读一些文本,特别是关于委托的iOS文档,所有协议方法都被称为 hook ,自定义委托对象需要实现。但是其他一些书,将这些挂钩命名为回调,它们之间有什么区别?它们只是不同的名称,但机制相同吗?除了Obj-C之外,其他一些编程语言,比如C,也得到了 hook ,和Obj-C一样吗?

4 个答案:

答案 0 :(得分:28)

这里的术语有点模糊。一般来说,两者试图取得类似的结果。

通常,回调是您在API中注册的函数(或委托),以便在处理流程中的适当时间调用(例如,通知您处理时间为某个阶段)

hook 传统上意味着一些更通用的东西,用于修改对API的调用(例如,修改传递的参数,监视被调用的函数)。在这个意义上,它通常比Java等高级语言所能达到的水平要低得多。

iOS 的上下文中,单词 hook 与上面的回调完全相同

答案 1 :(得分:12)

这两个词非常相似,有时可以互换使用。钩子是库中的一个选项,用户代码可以链接一个函数来改变库的行为。库函数不需要与用户代码并行运行;就像在析构函数中一样。

回调是一种特定类型的钩子,其中用户代码将启动库调用,通常是I / O调用或GUI调用,它将控制权交给内核或GUI子系统。然后,控制过程在中断或信号上“回调”用户代码,以便用户代码可以提供处理程序。

从历史上看,我见过用于中断处理程序的钩子和用于GUI事件处理程序的回调。我还看到当例程是动态代码中的静态链接和回调时使用的钩子。

答案 2 :(得分:3)

让我用Java语言回答。在Javascript中,全部使用回调挂钩事件。按此顺序,它们分别是一个更高层次的概念。

不幸的是,它们经常被错误地使用,从而导致混乱。

回调

从控制流的角度来看,回调是通常从参数中给出的函数,您需要在从函数返回之前执行该函数。

通常在异步情况下需要等待I / O时使用(例如HTTP请求,文件读取,数据库查询等)。您不想等待同步while循环,因此可以同时执行其他功能。

获取数据时,您(永久)放弃控制并使用结果调用回调。

function myFunc(someArg, callback) {
    // ...
    callback(error, result);
}

因为回调函数可能是尚未执行的某些代码,并且您不知道调用堆栈中函数的上方,所以通常不抛出错误,而是将错误作为参数传递给回调。有错误优先结果优先回调约定。

在Javascript世界中,大多数回调已被Promises取代,自ES2017 +起,您可以原生使用async/await来摆脱富含回调的意大利面条式代码,并使异步控制流看起来像是同步的

有时,在特殊的级联控制流中,您可以在函数中间运行回调,例如在Koa (web server) middleware中,您运行next(),它在堆栈中的所有其他中间件都运行完之后返回。

挂钩

钩子并不是一个明确定义的术语,但是在Javascript实践中,当您希望客户端(API /库用户,子类等)在控制流中定义明确的位置采取可选操作时,会提供钩子

因此,钩子可能是您在某点调用的某些函数(例如,自变量或类方法)。在数据库更新期间:

data = beforeUpdate(data);

// ...update

afterUpdate(result);

通常的意思是:

  • 挂钩可以是可选的
  • 通常需要等待钩子,即它们在那里可以修改某些数据
  • 每个钩子最多调用一个函数(与事件相反)

事件

在Javascript中,事件是在某些时间发出的,客户端可以订阅它们。事件发生时调用的功能称为侦听器-或因混淆而称为回调。为此,我宁愿避开“回调”一词,而改用“侦听器”一词。

这也是一种通用的OOP模式。

在前端有一个DOM interface用于事件,在node.js中,您具有EventEmitter界面。 ReactiveX中实现了复杂的异步版本。

事件属性:

  • 可能为同一事件订阅了多个侦听器/回调(要执行)。
  • 它们通常不接收回调,仅接收一些事件信息并同步运行
  • 通常,与钩子不同,它们不是用于在事件发射器的控制流中修改数据。发射器不在乎“是否有人在听”。它只是使用事件数据调用侦听器,然后立即继续。

示例:事件发生在数据流开始或结束,用户单击按钮或修改输入字段时。

答案 3 :(得分:2)

已经有两个很好的答案了,但是我想再提出一个证明条款" hook"和#34;回调"是相同的,可以互换使用:FreeRTOS赞成术语" hook"但承认"回调"作为一个等价术语,当他们说:

  

空闲任务可以选择调用应用程序定义的挂钩(或回调)功能 - 空闲挂钩。

     

tick中断可以选择调用应用程序定义的 hook(或回调)函数 - 勾选。

     

heap_1.c,heap_2.c,heap_3.c,heap_4.c和heap_5.c实现的内存分配方案可以选择包含malloc()失败挂钩(或回调)功能可以配置为在pvPortMalloc()返回NULL时调用。

来源:https://www.freertos.org/a00016.html