钩子和回调有什么区别?

coa*_*nor 29 hook callback

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

Att*_*ila 29

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

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

传统上是指用于修改调用API的目的,一些更普遍(例如修改传递的参数,监控调用的函数).在这个意义上,它通常比Java等高级语言所能达到的水平低得多.

iOS的上下文中,单词hook意味着与上面的回调完全相同的东西


小智 12

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

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

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


gom*_*osg 7

让我用Java语言回答。在Javascript中,回调钩子事件都被使用。按此顺序,它们分别是彼此更高层次的概念。

不幸的是,它们经常使用不当而导致混乱。

回呼

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

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

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

function myFunc(someArg, callback) {
    // ...
    callback(error, result);
}
Run Code Online (Sandbox Code Playgroud)

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

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

有时,在特殊的级联控制流中,您会在函数中间运行回调。例如,您运行的Koa(Web服务器)中间件Reduxnext()中间件在堆栈中的所有其他中间件都已运行之后返回。

钩子

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

因此,挂钩可能是您在某个时刻(例如,在数据库更新期间)调用的某些函数(例如,作为参数或类方法):

data = beforeUpdate(data);

// ...update

afterUpdate(result);
Run Code Online (Sandbox Code Playgroud)

通常,重点是:

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

React在其Hooks API中使用了钩子,它们(引用其定义)“是让您“钩住” React状态和生命周期功能的函数”,即它们使您可以更改React状态并在每次确定特定条件时运行自定义函数部分状态改变。

大事记

在Javascript中,事件在某些时间点发出,客户端可以订阅它们。事件发生时调用的函数称为侦听器 -或引起混乱的回调。为此,我宁愿避开术语“回调”,而改用术语“侦听器”。

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

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

事件的属性:

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

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


Gab*_*les 5

已经有两个很好的答案了,但我想再提供一个证据,术语“钩子”和“回调”是相同的,并且可以互换使用:FreeRTOS 支持术语“钩子”,但将“回调”视为等效术语术语,当他们说:

空闲任务可以选择调用应用程序定义的钩子(或回调)函数 - 空闲钩子。

滴答中断可以选择调用应用程序定义的钩子(或回调)函数 - 滴答钩子。

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

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