资讯专栏INFORMATION COLUMN

setTimeout与setInterval

Tangpj / 3268人阅读

摘要:工作线程执行异步任务,执行完成后把对应额回调函数封装成一条消息放到消息队列中主线程不断地从消息队列中取消息并执行。当消息队列为空时,主线程阻塞,直到消息队列再次非空。取决于何时被主线程的事件循环取到,并执行。

转自:http://palmer.arkstack.cn/201...
一:平时简单使用

1.setTimeout延迟一段时间执行一次(only one)

setTimeout(function, milliseconds, param1, param2, ...)
clearTimeout() // 阻止定时器运行
setTimeout(function(){ alert("Hello"); }, 3000); // 3s后弹出

2.setInterval 每隔一段时间执行一次 (Many times)

 setInterval(function, milliseconds, param1, param2, ...)
 
 e.g.
 setInterval(function(){ alert("Hello"); }, 3000); // 每隔3s弹出
 
 

3.setTimeout和setInterval的延时最小间隔是4ms;在JavaScript中没有任何代码是立刻执行的,但一旦进程空闲就尽快执行。所以 setTimeout 还是setInterval,设置的时间都是n毫秒被添加到队列中,而不是过n毫秒后立即执行。
二:进程与线程

1.模拟一个场景

有一个大型工厂

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

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

那么:

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

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

这个运行的车间(进程)里的工人,就是线程,可以有多个工人(线程)

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

在深入一点:

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

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

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

再深入:

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

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

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

三:JavaScript单线程

JavaScript这门语言的核心特征,就是单线程(是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个)。这和JavaScript最初设计是作为一门GUI变成语言有关,最初用于浏览器端,单一线程控制GUI是很普遍的做法。虽然JavaScript是单线程,当浏览器是多线程的!!!!!!!例如webkit或是Gecko引擎,可能有JavaScript引擎线程,界面渲染线程,浏览器事件触发线程,Http请求线程,读写文件的线程。

四:同步异步
1.同步(synchronous):假如一个函数返回时,调用者就能够得到预期结果(即拿到了预期的返回值或者看到了预期的效果)这就是同步函数

e.g.
alert("马上能看到我拉");
console.log("也能马上看到我哦");

2.异步(asynchronous):假如一个函数返回时,调用者不能得到预期结果,需要通过一定手段才能获得,这就是异步函数。

e.g.
setTimeout(function() {
    // 过一段时间才能执行我哦
}, 1000);




五:异步构成要素

一个异步过程通常是这样的:主线程发起一个异步请求,相应的工作线程(比如浏览器的其他线程)接受请求并告知主线程已收到(异步函数返回);主线程可以继续执行 后面代码,同时工作线程执行异步任务,工作线程完成工作号,告知主线程;主线程收到通知后,执行一定的动作(调用回调函数)

六:通信机制

异步过程的通信机制:工作线程将消息放到消息队列,主线程通过事件循环过程去取消息

七:事件循环Event Loop

主线程(js线程)只会做一件事,就是从消息队列里面取消息,执行消息,再取消息,再执行。消息队列为空时,就会等待直到消息队列变成非空。只有当前的消息执行结束,才会去取下一个消息。这种机制就叫做事件循环机制Event Loop,取一个消息并执行的过程叫做一次循环

工作线程是生产者,主线程是消费者。工作线程执行异步任务,执行完成后把对应额回调函数封装成一条消息放到消息队列中;主线程不断地从消息队列中取消息并执行。当消息队列为空时,主线程阻塞,直到消息队列再次非空。

八:setTimeOut(function,0)发生了什么

setTimeOut的function的任务异步执行,0不代表立即执行,而是将任务推到消息队列的最后,再由主线程的事件循环调用。
setTimeOut的最小时间不是0ms而是4ms

九:setInterval缺点

定时器指定的时间间隔,表示的是何时将定时器的代码添加到消息队列,而不是何时执行代码,所以真正何时执行代码的时间是不能保证的。取决于何时被主线程的事件循环取到,并执行。

 setInterval(function, N)

上面代码意味着,每隔N秒把function事件推到消息队列中,什么时候执行,就不知道了

上图可见,setInterval每隔100ms往队列中添加一个事件;100ms后,添加T1定时器代码至队列中,主线程中还有任务在执行,所以等待,some event执行结束后执行T1定时器代码;又过了100ms,T2定时器被添加到队列中,主线程还在执行T1代码,所以等待;又过了100ms,理论上又要往队列里推一个定时器代码,但由于此时T2还在队列中,所以T3不会被添加,结果就是此时被跳过;这里我们可以看到,T1定时器执行结束后马上执行了T2代码,所以并没有达到定时器的效果。

setInterval两个缺点:

使用setInterval时,某些间隔会被跳过

可能多个定时器会连续执行

十:链式setTimeOut

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

在严格模式下,第5版ECMAScript(ES5)禁止使用arguments.callee()。当一个函数必须调用自身的时候,避免使用arguments.callee(),通过要么给函数表达式一个名字,要么使用一个函数声明

上述函数每次执行的时候都会创建一个新的定时器,第二个setTimeOut使用了arguments.callee()获取当前函数的引用,并且为其设置另一个定时器。在一个定时器执行完前,不会向队列插入新的定时器(解决缺点一),保证定时器间隔(解决缺点二)

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

转载请注明本文地址:https://www.ucloud.cn/yun/94538.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
  • JavaScript 定时器

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

    王伟廷 评论0 收藏0
  • setIntervalsetTimeout

    摘要:第二个调用当前执行的函数,并为其设置另外一个定时器。使得在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔。 在自己用canvas画一个时钟时,画秒钟用的是利用图片将重复的线条遮住,但是会出现有两个秒钟线条同时存在,才想起setInterval有那么个坑,查了点资料,记录下,若有不对的或者未写到的点,还请大家指出,谢谢^_^ 在此之前先科普下这个学习点...

    BenCHou 评论0 收藏0

发表评论

0条评论

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