什么是回调函数?
回调函数是一个函数,将会在另一个函数完成执行后立即执行。回调函数是一个作为参数传给另一个函数的函数。这个回调函数会在传给的函数内部执行。
为什么我们需要回调?
客户端 JavaScript 在浏览器中运行,并且浏览器的主进程是单线程事件循环。如果我们尝试在单线程事件循环中执行长时间运行的操作,则会阻止该过程。从技术上讲这是不好的,因为过程在等待操作完成时会停止处理其他事件。
在上面的代码片段中,首先执行getMessage()函数,然后执行displayMessage()。两者都在浏览器的控制台窗口中显示了一条消息,并且都立即执行。
在某些情况下,一些代码不会立即执行。例如,如果我们假设getMessage()函数执行 API 调用,则必须将请求发送到服务器并等待响应。这时我们应该如何处理呢?
如何使用回调函数?
为了使用回调函数,我们需要执行某种无法立即显示结果的任务。为了模拟这种行为,我们用 JavaScript 的setTimeout()函数。该函数会暂停两秒钟,然后在控制台窗口中显示消息“ Hi,there”。
“显示的消息”将被显示在浏览器的控制台窗口中。在这种情况下,首先,我们需要等待getMessage()函数。成功执行此函数后,再执行displayMessage()函数。
回调的工作方式
从上一个例子可以看到,在getMessage()函数中,我们传递了两个参数。第一个参数是msg变量,该变量显示在浏览器的控制台窗口中,第二个参数是回调函数。
现在,你可能想知道为什么将回调函数作为参数进行传递 —— 要实现回调函数,我们必须将一个函数作为参数传给另一个函数。
在getMessage()完成任务后,我们将调用回调函数。之后,当调用getMessage()函数时,将引用传给displayMessage()函数,该函数就是回调函数。
注意,当调用getMessage()函数时,我们仅将其引用传给displayMessage()函数。这就是为什么你不会在它旁边看到函数调用运算符,也就是()符号。
Javascript 回调地狱
当多个异步函数一个接一个地执行时,会产生回调地狱。它也被称为厄运金字塔。
如何避免回调地狱?
可以使用多种技术来避免回调地狱,如下所示。
使用promise
借助 async-await
使用 async.js 库