根据此堆栈溢出answer,
作为参数传递的函数始终是回调,即使目的是同步调用该函数...
我已经了解了事件循环机制,该机制基本上说回调函数被推入等待队列并在同步代码完成(堆栈为空)之后执行,但是在以下代码中
function myfun(a, b, callback) {
console.log(a);
callback();
console.log(b);
}
function cb() {console.log('hi')}
myfun(1, 2, cb) // result: 1 hi 2
结果不是我预期的1 2 hi
,据我推断,只有触发某些“事件信号”(如setTimeout
)的回调函数才会被推入此类队列,但我找不到具体的参考支持吗?
答案 0 :(得分:1)
“回调”通常与异步过程(如ajax请求或附加到ui的事件处理程序)结合使用。在这种情况下,我们称它们为“回调”,因为它们需要在其他操作之后执行,并且很明显,在异步过程完成或触发后,程序的逻辑将在何处取回该“调用”,从而使我们在这里“返回”。
使用setTimeout()可以将其添加到事件循环堆栈中。使用promise,您可以在等待异步过程完成时在事件循环上调用堆栈。
您的代码没有做任何事情来中断代码的同步流。此代码段显示了即使我们添加了0超时(该超时应延迟操作),我们如何等待诺言以允许事件循环的堆栈运行。
function myfun(a, b, callback) {
console.log(a);
callback();
console.log(b);
}
function cb() {
console.log('hi')
}
myfun(1, 2, cb) // result: 1 hi 2
// same behavior as above
function myStaticFun() {
console.log(1);
cb();
console.log(2);
}
myStaticFun();
// now same as before using a promise to wait a moment and the event loop stack is invoked during the pause
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function myEventLoopInvokingFun(a, b, callback) {
console.log(a);
setTimeout(callback, 0)
await sleep(0);
console.log(b);
}
myEventLoopInvokingFun(1, 2, cb);
答案 1 :(得分:0)
这不一定意味着每个callback
都是asynchronous
,必须放入某个task queue
中,并且必须synchronous
个代码段执行一次(调用堆栈为空)完成。处理Promise
的回调函数是task queue
的候选函数。例如您的情况; cb
函数只是以同步方式运行;因此结果就是您所指示的1 hi 2
;但是,如果我们按以下方式修改您的代码:
function myfun(a, b, callback) {
console.log(a);
window.setTimeout(callback, 0);
console.log(b);
}
function cb() {
console.log('hi');
}
myfun(1, 2, cb) // result: 1 2 hi
这将导致1 2 hi
。即使我将超时设置为仅0
毫秒; cb
函数将在console.log
函数中的第二个myfun
之后输出。我建议您看一下MDN以及此good explanation的调用堆栈,事件循环和任务队列。希望这会有所帮助。