简体   繁体   中英

Javascript callback function not executing as intended

According to this stackoverflow answer ,

functions passed as parameters are always callbacks, even if the intention is that the function is called synchronously...

and I've learned the event loop mechanism which basically says that call back functions are push into a waiting queue and executed after synchronous code finishes(stack empty), however in the following code

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

the result is not 1 2 hi as I expected, from which I infer that only callback functions that fire some 'event signal' like setTimeout will be pushed into such queue but I can't find concrete reference to support it?

"Callbacks" are usually used in conjunction with asynchronous processes like ajax requests or event handlers attached to the ui. We call them "callbacks" in these cases since they need to be executed after something else and it is clear where the program's logic will pick back up this "call" after the async process is complete or triggered brings us "back" here.

Using setTimeout() you can add to the event loop stack. Using a promise you can invoke the stack on the event loop as you wait for an asynchronous process to finish.

Your code doesn't do anything to interrupt the synchronous flow of the code. This snippet shows how even though we have added a timeout of 0 which should delay the action, we can await a promise to allow the event loop's stack to run.

 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);

It does not necessarily mean that every a callback is asynchronous and must be put into a some task queue and to be executed once synchronous code pieces (call stack is empty) finishes. The callback functions dealing with Promise s are candidates for task queue . For instance in your case; cb function simply runs in a synchronous manner; so that the result is 1 hi 2 as you indicated; however if we modify your code as follows:

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

this will result in 1 2 hi . Even though I set the timeout to just 0 milliseconds; cb function will output after the second console.log within myfun function. I would recommend you to take a look at MDN and this good explanation of call stack, event loop, and task queues. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM