使用javascript(无setInterval)的无限定时器循环? [英] Infinite Timer Loop with javascript ( no setInterval)?

查看:120
本文介绍了使用javascript(无setInterval)的无限定时器循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人问我(由朋友)建立一个计时器(每秒写一行的无限计时器),但没有 setInterval

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 :

var i = 0;

    function k(myId, cb)
    {
        setTimeout(function ()
        {
            console.log(myId);
            cb();
        }, 1000);
    }

    function go()
    {
        i++;
        k(i, go);
    }

    go();

它正在运作。

问题是,我担心会有记忆压力。它实际上创建了一个递归,并在一段时间后(一周或某事) - 该过程将消耗大量内存。 (堆栈永远不会被释放)

The problem is that I'm afraid there's gonna be a memory pressure. It actually creates a recursion and after a while (week or something) - the process will consume much memory. (the stack is never deallocated)

如何更改我的代码以免耗费大量内存?

How can I change my code in order not to be much memory consume?

推荐答案

这不是递归



它可能看起来像递归,但是setTimeout不会产生递归。

It's not recursion

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

setTimeout的工作方式是立即返回。所以对 k 的调用立即结束,其堆栈被解除分配。

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

当超时实际发生并且调用 go 再次发生它不是从上次调用 k 开始,而是来自全局范围*。

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*.

*注意:我没有使用ECMAScript规范中定义的范围的严格含义。我的意思是调用 k ,就好像你用普通的< script>< / script> tag:也就是说,在任何其他函数调用之外。

* 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 <script></script> tag: that is to say, outside of any other function calls.

在您的特定情况下, k 函数创建的闭包中实际包含的内容非常少。唯一重要的闭包是对参数 cb myId 的引用。即便如此,它只持续大约一秒钟:

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
    }



可能更简单



我应该注意到你的代码相当复杂。它可以写得更简单,如果你只是这样编写它就不使用闭包(减去全局变量i):

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

这篇关于使用javascript(无setInterval)的无限定时器循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆