`

setTimeout()和setInterval()的区别和转换

阅读更多

【前言】

      接着上篇文章,这里介绍下setTimeout()和setInterval()的区别和转换

      setTimeout()和setInterval()经常被用来处理延时和定时任务。

 

【区别】

      ①setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式;

      ②setInterval()则可以在每隔指定的毫秒数循环调用函数或表达式,直到clearInterval把它清除

      ③从定义上我们可以看到两个函数十分类似,只不过前者执行一次,而后者可以执行多次,两个函数的参数也相同,第一个参数是要执行的code或句柄,第二个是延迟的毫秒数。

     很简单的定义,使用起来也很简单,但有时候我们的代码并不是按照我们的想象精确时间被调用的,很让人困惑

 

【详解】

(1)简单实例

      看个简单的例子,简单页面在加载完两秒后,写下Delayed alert!

setTimeout('document.write("Delayed alert!");', 2000);

      看起来很合理,我们再看个setInterVal()方法的例子

var num = 0;
        var i = setInterval(function() {
            num++;
            var date = new Date();
            document.write(date.getMinutes() + ':' + date.getSeconds() + ':' + 
                           date.getMilliseconds() + '<br>');
            if (num > 10)
                clearInterval(i);
        }, 1000);

   页面每隔1秒记录一次当前时间(分钟:秒:毫秒),记录十次后清除,不再记录。考虑到代码执行时间可能记录的不是执行时间,但时间间隔应该是一样的,看看结果

43:38:116
43:39:130
43:40:144
43:41:158
43:42:172
43:43:186
43:44:200
43:45:214
43:46:228
43:47:242
43:48:256

 

(2)原因剖析

      时间间隔几乎是1000毫秒,但不精确,这是为什么呢?原因在于我们对JavaScript定时器存在一个误解,JavaScript其实是运行在单线程的环境中的,这就意味着定时器仅仅是计划代码在未来的某个时间执行,而具体执行时机是不能保证的,因为页面的生命周期中,不同时间可能有其他代码在控制JavaScript进程。在页面下载完成后代码的运行、事件处理程序、Ajax回调函数都是使用同样的线程,实际上浏览器负责进行排序,指派某段程序在某个时间点运行的优先级。

      我们把效果放大一下看看,添加一个耗时的任务

function test() {
            for (var i = 0; i < 500000; i++) {
                var div = document.createElement('div');
                div.setAttribute('id', 'testDiv');
                document.body.appendChild(div);
                document.body.removeChild(div);
            }
        }
        setInterval(test, 10);
        var num = 0;
        var i = setInterval(function() {
            num++;
            var date = new Date();
            document.write(date.getMinutes() + ':' + date.getSeconds() + ':' + 
                           date.getMilliseconds() + '<br>');
            if (num > 10)
                clearInterval(i);
        }, 1000);

   我们又加入了一个定时任务,看看结果

47:9:222
47:12:482
47:16:8
47:19:143
47:22:631
47:25:888
47:28:712
47:32:381
47:34:146
47:35:565
47:37:406

   这下效果明显了,差距甚至都超过了3秒,而且差距很不一致。

   我们可以可以把JavaScript想象成在时间线上运行。当页面载入的时候首先执行的是页面生命周期后面要用的方法和变量声明和数据处理,在这之后JavaScript进程将等待更多代码执行。当进程空闲的时候,下一段代码会被触发

   除了主JavaScript进程外,还需要一个在进程下一次空闲时执行的代码队列。随着页面生命周期推移,代码会按照执行顺序添加入队列,例如当按钮被按下的时候他的事件处理程序会被添加到队列中,并在下一个可能时间内执行。在接到某个Ajax响应时,回调函数的代码会被添加到队列。JavaScript中没有任何代码是立即执行的,但一旦进程空闲则尽快执行。定时器对队列的工作方式是当特定时间过去后将代码插入,这并不意味着它会马上执行,只能表示它尽快执行。

   知道了这些后,我们就能明白,如果想要精确的时间控制,是不能依赖于JavaScript的setTimeout函数的。

 

(3)重复的定时器

      使用 setInterval() 创建的定时器可以使代码循环执行,到有指定效果的时候,清除interval就可以,如下例

var my_interval = setInterval(function () {
            if (condition) {
                //..........
            } else {
                clearInterval(my_interval);
            }
        }, 100);

       但这个方式的问题在于定时器的代码可能在代码再次被添加到队列之前还没有执行完成,结果导致循环内的判断条件不准确,代码多执行几次,之间没有停顿。不过JavaScript已经解决这个问题,当使用setInterval()时,仅当没有该定时器的其他代码实例时才将定时器代码插入队列。这样确保了定时器代码加入到队列的最小时间间隔为指定间隔。

      这样的规则带来两个问题

   1. 某些间隔会被跳过

   2.多个定时器的代码执行之间的间隔可能比预期要小

   为了避免这两个缺点,我们可以使用setTimeout()来实现重复的定时器

setTimeout(function () {
            //code
            setTimeout(arguments.callee, interval);
        }, interval)

    这样每次函数执行的时候都会创建一个新的定时器,第二个setTimeout()调用使用了agrument.callee 来获取当前实行函数的引用,并设置另外一个新定时器。这样做可以保证在代码执行完成前不会有新的定时器插入,并且下一次定时器代码执行之前至少要间隔指定时间,避免连续运行。

setTimeout(function () {
            var div = document.getElementById('moveDiv');
            var left = parseInt(div.style.left) + 5;
            div.style.left = left + 'px';
            if (left < 200) {
                setTimeout(arguments.callee, 50);
            }
        }, 50);

   这段定时器代码每次执行的时候,把一个div向右移动5px,当坐标大于200的时候停止

 

 

 

 

.

分享到:
评论

相关推荐

    使用自定义setTimeout和setInterval使之可以传递参数和对象参数

    在JavaScript编程中,`setTimeout` 和 `setInterval` 是两个非常重要的函数,它们用于执行异步操作,分别在指定的时间延迟后或每隔指定的时间间隔执行一次回调函数。然而,原生的 `setTimeout` 和 `setInterval` 在...

    动态时钟,利用setInterval

    在学习`setInterval`的过程中,你可能还会遇到`setTimeout`函数,它与`setInterval`类似,但只执行一次。了解它们的区别和使用场合也是很重要的。 总的来说,`setInterval`是JavaScript中的基础工具之一,理解并...

    JavaScript计时器用法分析【setTimeout和clearTimeout】

    JavaScript中的setTimeout和clearTimeout是两个非常重要的计时器函数,它们允许我们在指定的时间后执行一段代码,也可以取消之前设定的计时器。 首先,setTimeout函数的基本用法是`setTimeout(code, delay)`,其中...

    js定时间转换图片

    这个任务通常涉及到几个关键知识点:计时器(setTimeout 和 setInterval)、DOM操作(元素选择与修改)以及事件处理。接下来,我们将详细讨论这些核心概念。 1. **计时器**: - `setTimeout`: 该函数用于在指定的...

    动态转换头像.rar

    6. **动画原理**:可能用到requestAnimationFrame或者setTimeout/setInterval来创建平滑的动画效果。 7. **表单元素**:理解HTML表单和按钮元素的工作原理,以及如何与JavaScript交互。 8. **用户体验设计**:考虑...

    to-ms:使您的“ setTimeout”和“ setInterval”时间段更具可读性

    一个简单且人性化的毫秒转换实用程序,具有出色的链接。 安装 npm install to-ms // or yarn add to-ms 例子 var toMs = require ( 'to-ms' ) ; setTimeout ( function ( ) { /* do something */ } , toMs . ...

    javascript经典特效---类似FLASH的文字转换.rar

    3. **时间函数和定时器**:利用`setTimeout`或`setInterval`来控制动画的执行节奏,实现平滑过渡。 4. **动画框架**:可能会使用像jQuery的`.animate()`方法或GSAP(GreenSock Animation Platform)这样的库来简化...

    countdown倒计时获取验证码倒计时

    1. **setTimeout和setInterval**:`setTimeout`函数用于在指定的毫秒数后调用一次函数或执行某段代码,而`setInterval`则会在给定的时间间隔内重复执行某个函数。在倒计时应用中,通常会使用`setTimeout`,因为倒...

    javaScript图片转换特效

    6. **优化**:考虑到性能,可以使用`setTimeout`替代`setInterval`,避免在图片切换过程中连续触发。此外,预加载下一张图片,防止在切换时因加载延迟而出现空白。 总的来说,“javaScript图片转换特效”是网页动态...

    将源图像转换成动画派对表情符号

    通过改变元素的CSS属性(如位置、大小、颜色等)并利用requestAnimationFrame或setTimeout/setInterval来控制动画帧率,我们可以创建出流畅的动画效果。 在“将源图像转换成动画派对表情符号”的项目中,有几个关键...

    旋转木马转换图片.zip

    开发者可能使用了定时器(setTimeout或setInterval)来实现动态效果,以及CSS样式操纵来改变图片的位置和透明度,模拟旋转和过渡效果。 3. **`demo.html`**: 这是项目的主HTML文件,包含了旋转木马的结构和布局。...

    两个超级经典的图片转换代码(jQuery实现的)

    实现这个功能的关键在于利用jQuery的`fadeIn()`和`fadeOut()`方法进行淡入淡出效果,结合`setTimeout()`或`setInterval()`进行定时切换。同时,还可以添加导航箭头和索引点,增强用户体验。 第二个可能的经典代码是...

    javascript经典特效---图片转换效果.rar

    5. **计时器**:如果要实现自动切换,可以使用`setInterval`或`setTimeout`函数来定时执行图片更换。 6. **封装和模块化**:为了保持代码的整洁和可维护性,这些功能可以封装成一个函数或对象,避免全局变量的污染...

    javascript 倒计时

    3. **setTimeout和setInterval**:这两个函数是JavaScript中的定时器。`setTimeout(func, delay)`会在指定延迟后执行一次函数,而`setInterval(func, delay)`会每隔指定延迟重复执行函数。在倒计时应用中,我们通常...

    javascript经典特效---下载记时器脚本.rar

    在JavaScript中,`setTimeout`和`setInterval`是实现计时器功能的关键。`setTimeout`用于在指定的毫秒数后调用一个函数一次,而`setInterval`则会在给定的时间间隔内重复调用一个函数。下载计时器通常会使用`...

    前端大厂最新面试题-sohu.docx

    * setTimeout和setInterval函数绑定:将setTimeout和setInterval函数绑定到某个对象上,以便在定时器触发时正确地执行函数。 vm.on和vm.emit vm.on()和vm.emit()是Vue.js框架中的两个重要方法,用于实现组件之间的...

    南师大教育技术学考研笔记JavaScript入门经典.docx

    JavaScript还提供了丰富的对象机制,如Date对象用于处理日期和时间,定时器(setTimeout和setInterval)用于执行延迟或周期性任务,以及DOM对象模型用于操作网页元素。此外,Ajax(异步JavaScript和XML)技术使得...

    JavaScript小特效钟表 大笨钟.7z

    开发者可能使用了setTimeout或setInterval函数来定时更新钟表的时间显示,同时可能使用了CSS选择器和DOM操作来修改HTML元素的内容和样式,以反映当前时间。 总的来说,这个JavaScript小特效钟表项目是一个结合了...

    最简单倒计时

    - 需要注意的是,由于浏览器的异步执行机制,`setTimeout`和`setInterval`可能不会精确到毫秒,因此在处理倒计时时,需要进行适当的误差修正。 3. **HTML和CSS展示**: - HTML用于构建页面结构,可以创建一个包含...

    js 广州亚运会倒计时效果代码.zip

    2. **定时器(setTimeout或setInterval)**:JavaScript提供了`setTimeout`和`setInterval`函数来定期执行某段代码。在这里,`setInterval`可能被用来每隔一定时间(例如1秒)更新倒计时的显示。 3. **DOM操作**:...

Global site tag (gtag.js) - Google Analytics