在这一点上,我有一个问题,究竟什么是回调,是什么使它不同于高阶函数,以及它与回调队列的概念有什么关系?
来自MDN:回调函数
回调函数是作为参数传递到另一个函数中的函数,然后在外部函数中调用该函数来完成某种例程或操作。
看来与高阶函数的定义有重叠之处。传递(稍后调用)给另一个函数的函数。
这是回调的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包装器,它与wrapper (timer)接口。setTimeout传递给计时器API函数(asyncLog)和计时器(2000 to )。
当计时器功能(在web浏览器中)完成其工作后,只要JS调用堆栈是(1)空的,并且(2)已经处理了全局执行上下文中的所有内容,callback queue中的函数就会立即发送到callback queue中,以便在调用堆栈中调用。
因此,在处理最后一行console.log("me second")之后,Event循环将回调函数asyncLog从回调队列传递到调用堆栈,并执行它。
最后的命令是:
me first
me second
i am the last在第一个例子中,尽管我们将greeting称为“回调”函数,但我的理解表明,回调队列的整个机制被完全跳过:我们没有做任何异步的事情,也没有与web浏览器API接口(所有东西都是自包含在JS中的)。
如果是这样的话,为什么我们将传递给其他函数的函数称为回调(而不是简单的高阶函数),因为它们与回调队列和异步世界无关?
发布于 2018-07-30 15:04:51
高阶函数是一个函数,它以另一个函数作为参数,和/或将函数返回给调用者。
回调函数是一个传递给另一个函数的函数,期望另一个函数调用它。
因此回调本身并不一定是一个高阶函数,而是一个作为参数接收回调的函数。考虑一个非常常见的情况,DOM事件侦听器:
elem.addEventListener('click', console.log);在这里,.addEventListener是一个高阶函数,它接受另一个函数(console.log),然后调用它.虽然console.log在这里是一个回调函数,但在这种情况下,它本身并不是一个高阶函数。
事件循环是由底层运行时向您公开的机制。在这里,我们将设想必须使用数组作为队列手动执行此操作:
const queue = [];
const setTimeout = (f, ...args) => {
queue.push([f, args]);
};
const runQueuedCallbacks = () => {
let queued;
while (queued = queue.shift()) {
let [f, args] = queued;
f(...args);
}
};
setTimeout(console.log, 'first'); // queues a call to log
setTimeout(console.log, 'second'); // queues a call to log
console.log('zero-th'); // directly calls log, prints first
// at this point there's no more code to execute, so runQueuedCallbacks runs
// and sequentially steps through the enqueued callbacks.在现实生活中,由于微任务解析(也就是当排队的回调排队等待另一个回调时发生的情况),这比这要复杂一些,但这应该会给您一个不错的印象。
发布于 2019-05-22 18:53:56
高阶函数是将另一个函数作为参数并/或将函数返回给其调用方的函数。这里,作为参数传递的函数被调用为回调函数。但是,回调函数也可能是高阶函数,也可能不是。让我们看看例子。
function printString(callbackHof, callback_only, str) {
str +=' concated first';
callbackHof( callback_only,str);
}
function concatFirst(callback_only, str)
{
callback_only(str);
}
function concatAgain(str)
{
str += ' contated again';
console.log(str);
}
printString(concatFirst, concatAgain, 'anything');输出=“任何第一次被再次满足的内容”,以求澄清。
这里,printString()是一个高阶函数,它接受两个函数和一个字符串作为参数。printString()的函数参数是concatFirst()和concatAgain(),根据定义,这些concatFirst()和concatAgain()熏蒸是回调函数。
在这里,concatFirst()既是回调函数,也是高阶函数,因为它作为printString()的参数传递,然后将concatAgain()回调函数作为自己的输入。
而且,concatAgain()只是一个回调函数,因为它被调用时只有一个字符串参数&没有进一步的函数参数。
最后,回调队列是浏览器或javascript编译器在事件循环的帮助下完美地执行异步和回调操作的机制。
https://stackoverflow.com/questions/51579427
复制相似问题