setTimeout或setInterval?

据我所知,这两段JavaScript的行为方式相同:

选项A:

function myTimeoutFunction()
{
    doStuff();
    setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

选项B:

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

使用setTimeoutsetInterval之间有什么区别

卡卡西Davaid2020/03/11 11:18:26

和setInterval(expression,duration)之间最一般的区别是

setTimeout()将仅在指定的持续时间之后执行一次表达式。

然而,

setInterval()将在每个指定的持续时间之后在INFINITE-LOOP中执行表达式。

GreenSamA2020/03/11 11:18:26

只需添加已经说过的内容,但代码的setTimeout版本也将达到,Maximum call stack size这将使其无法运行。由于递归函数没有终止的基本情况,因此您不能使其永远运行

樱Harry2020/03/11 11:18:26

区别在控制台上很明显:

在此处输入图片说明

村村Gil2020/03/11 11:18:26

嗯,正如我刚学到的,setTimeout在一种情况下更好。我总是使用setInterval,我已经在后台运行了超过半小时。当我切换回该选项卡时,幻灯片放映(使用了代码)的变化非常快,而不是每5秒更改一次。实际上,随着我对其进行更多测试,它确实会再次发生,并且是否是浏览器的错误并不重要,因为使用setTimeout时,这种情况是完全不可能的。

小哥L2020/03/11 11:18:26

您的代码将具有不同的执行间隔,在某些项目(例如在线游戏)中,这是不可接受的。首先,应该做什么,以使您的代码以相同的间隔工作,您应该将“ myTimeoutFunction”更改为:

function myTimeoutFunction()
{
    setTimeout(myTimeoutFunction, 1000);
    doStuff();
}
myTimeoutFunction()

更改之后,它等于

function myTimeoutFunction()
{
    doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

但是,由于JS是单线程的,因此结果仍然不稳定。目前,如果JS线程忙于处理某些事情,它将无法执行您的回调函数,并且执行将被延迟2-3毫秒。如果您每秒执行60次,并且每次都有1-3秒的随机延迟,那将是绝对不可接受的(一分钟后大约为7200毫秒的延迟),我建议您使用以下方式:

    function Timer(clb, timeout) {
        this.clb = clb;
        this.timeout = timeout;
        this.stopTimeout = null;
        this.precision = -1;
    }

    Timer.prototype.start = function() {
        var me = this;
        var now = new Date();
        if(me.precision === -1) {
            me.precision = now.getTime();
        }
        me.stopTimeout = setTimeout(function(){
            me.start()
        }, me.precision - now.getTime() + me.timeout);
        me.precision += me.timeout;
        me.clb();
    };

    Timer.prototype.stop = function() {
        clearTimeout(this.stopTimeout);
        this.precision = -1;
    };

    function myTimeoutFunction()
    {
        doStuff();
    }

    var timer = new Timer(myTimeoutFunction, 1000);
    timer.start();

此代码将保证稳定的执行期限。即使线程将繁忙,您的代码将在1005毫秒后执行,下一次将有995毫秒的超时,结果将保持稳定。

凯达蒙2020/03/11 11:18:26

当您在setInterval中运行某些函数时,该函数的工作时间比timeout->更长,浏览器将被卡住。

-例如,doStuff()需要1500秒。要执行并执行:setInterval(doStuff,1000);
1)浏览器运行doStuff()耗时1.5秒。被执行;
2)〜1秒后,它将尝试再次运行doStuff()但是以前的doStuff()仍然会执行->因此浏览器将此运行添加到队列中(先完成后运行)。
3,4,..)将相同内容添加到下一个迭代的执行队列中,但是上一个迭代的doStuff()仍在进行中……
结果,浏览器被卡住了。

为防止此行为,最好的方法是在setTimeout中运行setTimeout以模拟setInterval
要更正setTimeout调用之间的超时,可以使用JavaScript的setInterval技术的自更正替代方法。

Tony老丝2020/03/11 11:18:26

换个角度看:setInterval确保代码以每个给定间隔(即1000ms,或您指定的时间)运行,而setTimeout设置它“等待”运行代码的时间。由于运行代码需要花费更多的毫秒,因此加起来总计为1000ms,因此setTimeout在不精确的时间(超过1000ms)再次运行。

例如,计时器/倒数不使用setTimeout完成,它们使用setInterval完成,以确保不延迟并且代码以确切的给定间隔运行。

L前端2020/03/11 11:18:26

setInterval和setTimeout都返回一个计时器ID,您可以使用该ID取消执行,即在触发超时之前。要取消,您可以这样调用clearInterval或clearTimeout:

var timeoutId = setTimeout(someFunction, 1000);
clearTimeout(timeoutId);
var intervalId = setInterval(someFunction, 1000),
clearInterval(intervalId);

同样,当您离开页面或关闭浏览器窗口时,超时也会自动取消。

米亚Near2020/03/11 11:18:26

我使用setTimeout。

显然,不同之处是setTimeout调用了该方法一次,setInterval重复调用了该方法。

这是一篇很好的文章,解释了它们之间的区别:教程:带有setTimeout和setInterval的JavaScript计时器

A小宇宙2020/03/11 11:18:26

setInterval使取消将来执行代码变得更加容易。如果使用setTimeout,则必须跟踪计时器ID,以防日后要取消它。

var timerId = null;
function myTimeoutFunction()
{
    doStuff();
    timerId = setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

// later on...
clearTimeout(timerId);

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
var timerId = setInterval(myTimeoutFunction, 1000);

// later on...
clearInterval(timerId);
TomSam2020/03/11 11:18:26

它们的目的非常不同。

setInterval()
   -> executes a function, over and over again, at specified time intervals  

setTimeout()
   -> executes a function, once, after waiting a specified number of milliseconds

就这么简单

更多详细信息,请参见http://javascript.info/tutorial/settimeout-setinterval

JinJinTom2020/03/11 11:18:26

setInterval()

setInterval()是基于时间间隔的代码执行方法,具有达到间隔时重复运行指定脚本的本机能力。脚本作者不应其嵌套在其回调函数中以使其循环,因为它默认情况下循环除非您致电,否则它将一直间隔触发clearInterval()

如果要循环播放动画或时钟滴答声的代码,请使用setInterval()

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setInterval(doStuff, 5000);

setTimeout()

setTimeout()是,将执行一个脚本仅基于时间的代码执行方法一次到达的时间间隔时。除非您通过将对象嵌套在调用运行的函数中来调整它来循环脚本,否则不会再次重复setTimeout()如果适合循环播放,除非您致电,否则它将持续间隔触发clearTimeout()

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setTimeout(doStuff, 5000);

如果您希望在指定时间段后发生某件事,请使用setTimeout()这是因为仅在达到指定间隔时才执行一次。

Stafan小小2020/03/11 11:18:26

他们本质上试图做同样的事情,但是这种setInterval方法比该setTimeout方法更加准确,因为要setTimeout等待1000ms,然后运行该函数,然后设置另一个超时。因此,等待时间实际上超过了1000毫秒(如果函数执行时间较长,则等待时间会更长)。

尽管有人可能会认为setInterval将执行完全相同每1000毫秒,这是需要注意的重要setInterval也将推迟,因为JavaScript是不是多线程的语言,这意味着-如果有运行脚本的其他部分-区间将有等待完成。

此Fiddle中,您可以清楚地看到超时将落在后面,而间隔几乎总是以近1个呼叫/秒的速度(脚本正在尝试执行)。如果将顶部的速度变量更改为类似20的小值(这意味着它将尝试每秒运行50次),则该间隔将永远不会达到平均每秒50次迭代。

延迟几乎总是可以忽略不计,但是如果您要编写非常精确的内容,则应该使用自调整计时器(本质上是基于超时的计时器,它会根据所创建的延迟不断进行自我调整)

用户70493023002020/03/11 11:18:26

setTimeout如果您想取消超时,我发现该方法更易于使用:

function myTimeoutFunction() {
   doStuff();
   if (stillrunning) {
      setTimeout(myTimeoutFunction, 1000);
   }
}

myTimeoutFunction();

同样,如果函数中出现问题,它将在第一次出现错误时停止重复,而不是每秒重复一次错误。