资讯专栏INFORMATION COLUMN

setInterval与setTimeout

BenCHou / 405人阅读

摘要:第二个调用当前执行的函数,并为其设置另外一个定时器。使得在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔。

在自己用canvas画一个时钟时,画秒钟用的是利用图片将重复的线条遮住,但是会出现有两个秒钟线条同时存在,才想起setInterval有那么个坑,查了点资料,记录下,若有不对的或者未写到的点,还请大家指出,谢谢^_^

在此之前先科普下这个学习点

进程与线程的区别

借用阮一峰大大借用的比喻,实现一个小实例:

有一个大型工厂

工厂里有若干车间,每次只能有一个车间在作业

每个车间里有若干房间,有若干工人在流水线作业

那么:

一个工厂对应的就是计算机的一个CPU,平时讲的多核就代表多个工厂

每个工厂里的车间,就是进程,意味着同一时刻一个CPU只运行一个进程,其余进程在怠工

这个运行的车间(进程)里的工人,就是线程,可以有多个工人(线程)协同完成一个任务

车间(进程)里的房间,代表内存。

再深入点:

车间(进程)里工人可以随意在多个房间(内存)之间走动,意味着一个进程里,多个线程可以共享内存

部分房间(内存)有限,只允许一个工人(线程)使用,此时其他工人(线程)要等待

房间里有工人进去后上锁,其他工人需要等房间(内存)里的工人(线程)开锁出来后,才能才进去,这就是互斥锁(Mutual exclusion,缩写 Mutex)

有些房间只能容纳部分的人,意味着部分内存只能给有限的线程

再再深入:

如果同时有多个车间作业,就是多进程

如果一个车间里有多个工人协同作业,就是多线程

当然不同车间之间的工人也可以有相互协作,就需要协调机制

感觉一下子就记住了这两者的概念及区别
1.setTimeout

setTimeout()用来指定某个函数或字符串在指定的毫秒数之后执行;它会返回一个整数,表示定时器的编号,这个值可以传递给clearTimeout()用来清除定时器

/* 一秒钟后在控制台上打印出111 */

也可以写成字符串参数的形式,但这种形式会造成javascript引擎两次解析,降低性能(1.引擎内部使用eval()函数,将字符串转为代码;2.代码执行的解析)

2.在IE浏览器中使用定时器存在部分小问题:

IE9浏览器只允许setTimeout有两个参数,不支持更多的参数,会在控制台输出NaN

可以使用IIFE来进行参数的传递

setTimeout((function(x, y) {
    console.log(x+y);
})(1,2), 1000)

IE8浏览器不允许向定时器中传递事件对象event

可以将事件对象中的某些属性保存在变量中传递进去

div.onclick = function(e) {
    e = e || event;
    let type = e.type;
    setTimeout(function(e) {
        console.log(e.type);  /* 报错 */
        console.log(type);  /* click */
    }, 1000)
}
3.setInterval

setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行

HTML5标准规定,setTimeout的最短时间间隔是4ms;setInterval的最短间隔时间是10ms,所以,小于了最短的时间间隔会被调整到最短时间间隔

使用setInterval()时,定时器代码可能在代码再次被添加到队列之前还没有完成执行,导致定时器代码连续执行了多次,但之间没有任何停顿。javascript引擎的解决方式就是:使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到执行队列中,确保定时器代码加入到队列中的最小时间间隔为指定间隔

但这也会导致两个问题:1.某些间隔被跳过2.多个定时器的代码执行之间的间隔可能比预期的小

如下图:

4.链式setTimeout

使用链式setTimeout来解决我画时钟的那个问题

setTimeout(function fn() {
    console.log(111);
    setTimeout(fn, 1000);
}, 1000)

使用链式模式调用setTimeout(),函数执行的时候都会创建一个新的定时器。第二个setTimeout()调用当前执行的函数,并为其设置另外一个定时器。使得在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔。而且,它可以保证在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行

正在努力学习中,若对你的学习有帮助,留下你的印记呗(点个赞咯^_^)

往期好文推荐:

画三角形

webpack打包(有面试题)

时间戳转换成时间日期格式及去重

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96934.html

相关文章

  • process.nextTick() 、setTimeout()、setInterval() 运行机

    摘要:注意如果主逻辑的代码执行时间已经超过了第二个参数设置的时间,那么等运行到该回调函数时,它会忽略掉这个时间,并立即执行。如果某一个进行大量的计算,那么它就会阻塞在当前的回调函数中,等待该计算完成后,再执行下一个的回调函数。 setTimeout() ​ JavaScript是一个单线程的语言,也就是说它同一时间只能执行一段代码,接下来我们通过两个例子说明一下单线程语言和多线程语言的...

    lscho 评论0 收藏0
  • setTimeoutsetInterval的区别和nodejs中的差异

    摘要:关于定时器的源码在文件中,进入就关于定时器的一些设计解释,因为是做服务端代码,在内部等大部分事件都会创建一个定时器,任何时间都可能存在大量的定时器任务,所以设计一个高效的定时器是很有必要的。 博客文章地址 setTimeout与setInterval setTimeout 和 setInterval 是我们在 javaScript 中经常用到的定时器,setTimeout 方法用于...

    meislzhua 评论0 收藏0
  • setTimeoutsetInterval(一)

    摘要:看一下例子一些其他的代码假定处理程序需要执行,这时虽然在添加了定时器代码,但是仍旧需要等待事件完成后才能够执行。缺点某些间隔会被跳过多个定时器的代码执行之间的间隔可能会比预期小。 一. setTimeout 1. 定义 window.setTimeout(func,[delay,param1,param2,····]); window.setTimeout(code,[delay]);...

    Betta 评论0 收藏0
  • setTimeoutsetInterval

    摘要:工作线程执行异步任务,执行完成后把对应额回调函数封装成一条消息放到消息队列中主线程不断地从消息队列中取消息并执行。当消息队列为空时,主线程阻塞,直到消息队列再次非空。取决于何时被主线程的事件循环取到,并执行。 转自:http://palmer.arkstack.cn/201...一:平时简单使用 1.setTimeout延迟一段时间执行一次(only one) setTimeout(f...

    Tangpj 评论0 收藏0
  • JavaScript 定时器

    摘要:定时器方法相关方法有四种。返回值返回值是一个正整数,表示定时器的编号。这个值可以传递给来取消该定时器。使用方法很简单只有一个参数,该参数为您要取消定时器的标识符。用法很简单当代码运行到这行的时候,会取消所设置的定时器。 简单介绍在JavaScript中定时器有两个 setInterval() 与 setTime...

    王伟廷 评论0 收藏0

发表评论

0条评论

BenCHou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<