【发布时间】:2019-01-05 20:18:06
【问题描述】:
此时,我有一个问题:回调到底是什么,它与高阶函数有何不同,以及它与概念有何关系回调队列?
来自 MDN:Callback function
回调函数是作为参数传递给另一个函数的函数,然后在外部函数内部调用该函数以完成某种例程或动作。
看起来与高阶函数的定义有重叠。一个被传递(然后被调用)给另一个函数的函数。
这是回调的 MDN 示例:
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
到目前为止毫无疑问。
然后我遇到了事件循环和回调队列的想法。
console.log("me first");
setTimeout(function asyncLog() {
console.log("i am the last")
}, 2000);
console.log("me second")
原来seTimeout 函数实际上是一个JavaScript 包装器,它在后台与Web 浏览器API(计时器)进行接口。 setTimeout 将一个函数 (asyncLog) 和计时器 (2000ms) 传递给 Timer API。
当计时器功能(在 Web 浏览器中)完成其工作时,将在 JS 调用堆栈为 (1) 空时发送 callback queue 中的函数 asyncLog 准备在调用堆栈中调用(2) 已经处理了全局执行上下文中的所有内容。
所以在处理完最后一行console.log("me second") 之后,事件循环将回调函数asyncLog 从回调队列传递到调用堆栈,并执行它。
最后的顺序是:
me first
me second
i am the last
在第一个示例中,尽管我们将 greeting 称为“回调”函数,但我的理解表明回调队列的整个机制被完全跳过:我们没有做任何异步的事情,我们也没有与 Web 浏览器 API 接口(一切都包含在 JS 中)。
如果是这样,为什么我们将传递给其他函数的函数称为回调(而不是简单的高阶函数),而它们与回调队列和异步世界无关?
【问题讨论】:
-
高阶函数 (HOF) 是返回函数的函数,而不是简单值。回调是一个函数,一旦(通常是异步的)过程完成,它就会被其他东西“回调”;回调可以返回一个值或一个函数,或者什么都不返回。因此,回调可能也可能不是 HOF,具体取决于回调它的 API。我不清楚你在哪里看到了冲突。
-
@JonasW。我指的是问候功能。
-
是的,第一个例子不是异步的,回调是立即调用的。回调可能会或可能不会最终被放置在回调队列中,具体取决于调用它的内容。我仍然不确定这如何导致您的结论“如果是这样......”。
-
没关系,看来我得仔细阅读了。
-
@jonrsharpe 说得通乔纳森。只有当 Web 浏览器 API 将函数“推送”到回调队列中时,它才会碰巧出现在回调队列中? (就像在 setTimeout 示例中一样)。
标签: javascript callback functional-programming