• 聊聊setTimeout和setInterval线程


    在聊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而已。
  • 相关阅读:
    [USACO14DEC] Cow Jog_Gold 牛慢跑(金)题解
    [USACO16DEC]Moocast(gold)奶牛广播-金 题解
    [USACO17FEB]Why Did the Cow Cross the Road III S题解
    [USACO4.3]逢低吸纳Buy Low, Buy Lower题解
    洛谷P5057 [CQOI2006]简单题题解
    ksum及二维版本
    [Noip2015] 信息传递
    数据库常用操作
    解决Mac连接MySQL需要输入绝对路径的问题
    在MAC上安装OpenCV(C++)
  • 原文地址:https://www.cnblogs.com/thomson-fred/p/9252259.html
Copyright © 2020-2023  润新知