简体   繁体   中英

Having a hard time with callbacks

Learning about callbacks and the solution to this problem eludes me. It should print a number every second counting down until zero. Currently, it logs the numbers from 10 - 0 but all at once and continues in an infinite loop.

Please help me to gain a better understanding of this situation. I have read up on callbacks and have a conceptual understanding but execution is still a bit tricky.

var seconds = 0;

var countDown = function(){
    for(var cnt = 10; cnt > 0; cnt--){
        setTimeout(function(x){
            return function(){
                seconds++
                console.log(x);
            };
        }(cnt), seconds * 1000);
    }
}
countDown()

The way your code is working now, it executes a for loop with cnt going from 10 to 1. This works. On each iteration, it schedules a new function to be run in seconds * 1000 milliseconds, carefully and properly isolating the value of cnt in x each time. The problem is that seconds is 0 , and it will only be changed once a callback executes; but by the time a callback executes, all of them will already have been scheduled for execution. If you need seconds * 1000 to vary while you're still scheduling them all (while the for loop is still running), you need to change seconds in the loop, rather than inside one of the callbacks.

Read up on IIFEs to see how they work. In this situation, you're creating a closure of the value you want to print. You had the right idea, but your syntax was off.

var seconds = 0;

var countDown = function () {
    var cnt = 10;

    // simplify your loop
    while (cnt--) {

        // setTimeout expects a function
        // use an IIFE to capture the current value to log
        setTimeout((function (x) {

            // return the function that setTimeout will execute
            return function (){
                console.log(x + 1);
            };
        }(cnt)), (++seconds) * 1000);
    }
};
countDown();

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