Javascript执行机制(setTimeout/Promise)

1.关于javscript

    javascript是一门单线程语言,在最近的html5中提出了web-worker,但javascript是单线程这一核心仍未改变,所以一切javascript版的“多线程”都是用单线程模拟出来的,javascript就是一门单线程语言。

2.javscript的事件循环

    既然js是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理js任务也需要一个一个的顺序执行。如果一个任务耗时过长,那么最后一个任务也必须等着。那么问题来了,如果我们想浏览新闻,但是新闻包含的超清图片加载很慢,难道我们的网页要一只卡到图片完全现实出来?因此聪明的程序员将任务认为两类:同步任务,异步任务

当我们打开网站时,网页渲染过程就是一大堆同步任务。执行过程用文字描述的话就是

    1.同步任务和异步任务分别进入不同的执行场所,同步的进去主线程,异步的进入enent table并注册函数。

    2.当指定的事情完成时,event table会将这个函数移步到 event queue 

    3.主线程的任务执行完毕为空,会去event queue读取对应的函数,进入主线程执行

    4.上诉过程会不断重复,也就是常说的event loop(事件循环)

    实例图:

疑问是:那怎么直到主线程的执行栈为空啊?原因是:js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去event queue那里检查是否用等待被调用的函数。

3.setTimeout  的执行方式是异步执行,用处一般为,延迟指定时间再执行移步函数。


根据前面的结论,上诉代码的打印顺序为 2,三秒后打印1 ,印证正确。

但是当遇到下面代码的时候


结果是打印1 的结果需要的时间远远超过3秒,这不符合我们想要的预期,我们想要的就是三秒后打印1 ,那么先看一下执行结果

    1.console.log(1)进入event table并注册,计时开始

    2.执行sleep函数,很慢,但是event table里的计时仍在继续

    3.3s到了 计时事件完成,console.log(1)进去event queue,但是此时主线程里的sleep还没有执行完成,console.log(1)只能继续等

    4.sleep执行完啦,console.log(1)进入主线程,从而执行

我们知道setTimeout 这个函数,是经过指定时间后,把要执行的任务加到event queue中,又因为单线程任务需要一个一个的执行,如果前面的任务需要的时间太久,此时setTimeout 的延时时间就会出现比较大的偏差。

4.setInterval

    对于执行顺序而言,setInterval会每隔指定的时间将注册的函数只如event queue,如果前面任务耗时太久,那么同样需要等待。

唯一需要注意一点的是,对于setInterval而言,我们知道不是每过指定时间就执行fn,而是每过指定时间就会有fn进入event queue。一旦setInterval的回调函数执行时间超过了延迟的时间,那么就完全看不出来有时间间隔了

5.promise

    对于promise而言,我们需要对js的执行了解的更细致一些,如下

    1.macro-task(宏任务):包括整体script代码,setInterval,setTimeout

    2.micro-task(微任务):promise ,process.nexttrick(nodejs的内容)

不同类型的任务会进入对应的event queue,比如setInterval,setTimeout会进入相同的event queue。

事件循环的顺序决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。看一下代码


分析一下上图代码,加深一下理解,(1)这段代码作为宏任务进入主线程,先遇到settimeout,那么将其回调函数分发到宏任务的event queue上,(2)接下来遇到promise,new promise立即执行,then函数分发到微任务的event queue中,(3)接下来遇到console.log()立即执行。(4)然后,整体script代码作为第一个宏任务执行结束,看看有哪些微任务,我们发现then在微任务event queue里,则执行,(5)第一轮循环事件结束,开始第二轮循环,当然是从宏任务的event queue开始,我们发现了宏任务event queue中的settimeout对应的回调函数,则立即执行。

图例如下:

6.下面一个例子练习


如果不会请看引用地址:https://juejin.im/post/59e85eebf265da430d571f89

结语:

1。javascript是一门单线程语言

2.Event Loop 是javascript的执行机制。

你可能感兴趣的:(Javascript执行机制(setTimeout/Promise))