Infinite Timer Loop with javascript ( no setInterval)?

后端 未结 3 2161
难免孤独
难免孤独 2020-12-28 21:20

I was asked (by a friend) to build a timer (infinite one which writes a line every second), but without setInterval.

I solved it with :



        
3条回答
  •  囚心锁ツ
    2020-12-28 21:32

    It's not recursion

    It may look like recursion, but setTimeout does not create recursion.

    The way setTimeout works is that it returns immediately. So the call to k ends immediately with its stack deallocated.

    When the timeout actually happens and the call to go happens again it is not from the point of the previous call to k but from the global scope*.

    * Note: I'm not using the strict meaning of scope as defined in ECMAScript spec here. What I mean is the call to k will be made as if you have written it in a plain tag: that is to say, outside of any other function calls.

    Regarding your concern over the closure

    In your specific case, there is very little that's actually enclosed in the closure created by the k function. The only significant closure is the reference to the arguments cb and myId. And even then it only lasts for approximately one second:

     #1   function k(myId, cb) {
     #2        setTimeout(function(){
     #3            console.log(myId); // there is a closure here to myId
     #4            cb();              // and another one for cb
     #5
                 /* But at this point in the function, setTimeout ends
                 * and as the function returns, there are no remaining
                 * references to either "cb" or "myId" accessible
                 * anywhere else. Which means that the GC can immediately
                 * free them (though in reality the GC may run a bit later)
                 */
      #6       }, 1000); // So one second is roughly the longest the closure lasts
        }
    

    Could be simpler

    I should note that your code is fairly convoluted. It can be written simpler, and without using closures at all (minus the global variable i) if you simply write it like this:

    // Simpler, does exactly the same thing:
    var i = 0;
    function go () {
        console.log(i);
        i++;
        setTimeout(go, 1000); // callback
    }
    go();
    

提交回复
热议问题