在聊setTimeout和setInterval这两个事件的前,先聊另外一个与之密切关联的知识点,那就是线程(thread)。而线程有常常跟另外一个词语--“进程”一起出现。那么何为线程?何为线程呢?关于线程,维基百科上是这么解释的:Thread (computing), a sequence of instructions that may execute in parallel with others(可能与其他指令并行执行的指令序列)。而进程是这么解释的:Process (computing), a computer program, or running a program concurrently with other programs(一种计算机程序,或与其他程序同时运行一个程序)。看起来有点绕,那么举一个形象点的例子,比如说打开电脑桌面的QQ,那么这个就是一个进程,而你可以在QQ上同时跟不同的人聊天、发离线文件、 发照片,那么这一个个操作就是线程。“与其他程序同时运行一个程序”,前面一个程序指的就是线程,而后面一个程序指的才是进程。
 
在js解析器中,js的执行是单线程的,也就是说一个进程执行过程中只能执行一个操作,不能同时执行几个操作。这个与其他后端的语言,如java,pyhton,甚至是js写的node.js有较大区别,这跟主要处理的业务对象是有关系的。另外一点,我们还需要区分浏览器的线程问题,浏览器是多线程的,除了js引擎线程,它还同时执行其他操作,例如:UI渲染线程,http请求线程,EventLoop轮询的处理线程等等。
 
讲了一大堆线程和进程,那么js究竟是如何处理setTimeout和setInterval的呢?
先举两个例子:
例子一:

setTimeout(
function colorTurn(){
box1.style.backgroundColor="yellow";
},3000);
box1.style.backgroundColor="blue";
 
在浏览器上:盒子先显示蓝色,3秒后显示黄色
 
 
 
例子二:

setInterval(
function colorTurn(){
box2.style.backgroundColor="yellow";
},3000);
box2.style.backgroundColor="blue";

 在浏览器上:盒子先显示蓝色,3秒后显示黄色

 

结果与例子一是一样的,但实际上,setInterval与setTimeout是有很大区别的,setTimeout只执行一次,而setInterval以函数内的时间参数为间隔不断执行,直到用clearInterval清除。可以用循环回调函数实现加法来验证setInterval,我在这里就不写出来了。
 
例一抽象出来的函数定义:
function process1(){
//do something}
setTimeout(fucntion process2(){
//do something
},3000)
function process3(){
//do something}
 
例二抽象出来的函数定义:
function process1(){
//do something}
setInterval(fucntion process2(){
//do something
},3000)
function process3(){
//do something}
 
这两个函数都涉及到了我上面谈到的线程问题,setTimeout是使函数延迟一定时间后再执行,setInterval是使函数以一定时间间隔执行。
当js执行setTimeout函数时,会延迟一定的时间才执行。例一中,函数执行的顺序为process1-process3-process3。由于js解析器是单线程的,所以必须是一条命令执行完后才到下一条命令,所以process2必须等Process3甚至后面的process4执行完了,3秒钟时间间隔到了它才会去检查线程,如果空闲,它会马上执行,如果有程序在执行,那么它会等当前程序执行完之后再执行。那么,如果process3执行时间超过了3秒呢?这种情况下,process2会一直等待,直到process3执行完毕它才执行。
同理,setInterval函数也是如此。不同的是,它会每隔一定时间,在这里是3秒钟检查一下线程队列,如果没有程序(函数)在执行,那么它执行,如果有程序在执行,那么它会继续等待,直到下一次的3秒之后。
 
再深入一点:
如果是setTimeout(或setInterval)里面嵌套setTimeout(或者setInterval)呢?那么还是那个原理,函数按序进入执行堆栈,必须是一段程序执行完后才会执行下一段程序。嵌套在里面的setTimeout会在上级setTimeout基础上继续等待一段时间,当等待时间到后,检查线程队列,如果空闲,就执行,如果有程序在执行,就继续等待。执行的顺序是外面的setTimeout会先于里面的setTimeout。
 
另外有一点值得了解一下:
setTimeout和setInterval都是window的函数,所以setTimeout和setInerval也可以写成window.setTimeout和window.setInterval。平时为了方便,往往省去了window而已。

聊聊setTimeout和setInterval线程的更多相关文章

  1. 你真的了解setTimeout和setInterval吗?

    博客园的代码排版真难用,编辑时候是好的,一保存就是乱了——本文也同时发表在我另一独立博客上 你真的了解setTimeout和setInterval吗?,可以移步至这里吧 setTimeout和setI ...

  2. [转]你真的了解setTimeout和setInterval吗?

    原文: http://qingbob.com/difference-between-settimeout-setinterval/ setTimeout和setInterval的基本用法我们一带而过: ...

  3. 前端开发:setTimeout与setInterval 定时器与异步循环数组

    前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的, ...

  4. setTimeout,setInterval原理

    function a() { setTimeout(function(){alert(1)},0); alert(2); } a(); 和其他的编程语言一样,Javascript中的函数调用也是通过堆 ...

  5. setTimeout和setInterval的注意事项

    精准问题 setTimeout的问题在于它并不是精准的,例如使用setTimeout设定一个任务在10ms后执行,但是在9ms后,有一个任务占用了5ms的cpu时间片,再次轮到定时器执行时,时间已经过 ...

  6. Javascript定时器(二)——setTimeout与setInterval

    一.解释说明 1.概述 setTimeout:在指定的延迟时间之后调用一个函数或者执行一个代码片段 setInterval:周期性地调用一个函数(function)或者执行一段代码. 2.语法 set ...

  7. JavaScript的setTimeout和setInterval的深入理解

    发表过一片博客<跟着我用JavaScript写计时器>,比较基础.....有网友说应该写一下setTimeout的原理和机制,嗯,今天就来写一下吧: 直奔主题:setTimeout和set ...

  8. setTimeout()和setInterval() 何时被调用执行

    定义 setTimeout()和setInterval()经常被用来处理延时和定时任务.setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔 ...

  9. 【JavaScript】JavaScript中的Timer是怎么工作的( setTimeout,setInterval)

    原文(http://www.yeeyan.org/articles/view/luosheng/24380) 作为入门者来说,了解JavaScript中timer的工作方式是很重要的.通常它们的表现行 ...

随机推荐

  1. 花了一晚上时间,终于把Python的基本用法归纳好了!

    一.内置函数 1. complex([real[,imag]]) 返回一个复数,实部 + 虚部*1j,或者把字符串或者数字转成复数形式. 参数可以是复数表达式,也可以是字符串.当参数是字符串的时候,数 ...

  2. 机器学习技法笔记:05 Kernel Logistic Regression

    Roadmap Soft-Margin SVM as Regularized Model SVM versus Logistic Regression SVM for Soft Binary Clas ...

  3. 关于如何使`(a === 1 && a === 2 && a === 3)`返回`true`问题的思考

    看见这个面试题目,第一反应就是在变量a取值时进行了一些改变,那就要用getter,关于存取器的介绍可以看这里 var temp = 1; Object.defineProperty(window, ' ...

  4. python tricks

    1. cities = ['Marseille', 'Amsterdam', 'New York', 'Londom'] # the good way for i, city in enumerate ...

  5. Java运行环境(win10)

    系统安装Java后,配置运行环境,我的系统是win10,之前随便装了,没想到最近执行javac命令报错,(网上找了一堆都没用)处理方式如下: 环境变量-新建:变量名:%JAVA_HOME%  变量值: ...

  6. SpringBoot初探(上传文件)

    学了Spring,SpringMVC,Mybatis这一套再来看SpringBoot,心里只有一句握草,好方便 这里对今天做的东西做个总结,然后在这之间先安利一个热部署的工具,叫spring-DevT ...

  7. es6中的对象的可计算的属性名

    先简单的啰嗦一下对象的属性: var obj = { a:2 } 要访问obj中a的位置,方法:1. obj.a     //2            2..obj ["a"]   ...

  8. Xamarin.Android 调用原生的Jar包

    我们有时候会从Android原生开发(Java)转移到Xamarin.Android开发时,需要将过去写好的Android Class Library直接嵌入到Xamarin.Android底下使用, ...

  9. Linux压力测试软件Stress安装及使用

    一.安装 yum install -y epel-release yum install stress -y 二.参数说明 -? --help 显示帮助信息 --version 显示软件版本信息 -t ...

  10. [转]debian9 安装任意版本mysql

    Debian 9 - Install MySQL Server The steps below will show you how to install whichever version of My ...