1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 深入理解JavaScript执行机制

深入理解JavaScript执行机制

时间:2020-04-20 11:02:40

相关推荐

深入理解JavaScript执行机制

web前端|js教程

javascript

web前端-js教程

本篇文章给大家带来的内容是关于深入理解JavaScript执行机制,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

php 仿美团网源码,vscode自定义调试命令,ubuntu的ppa,本机tomcat无法启动,水边的爬虫,php支付接口源码,荆州高效seo推广多少钱,pos机 网站源码lzw

首先我们大家都了解的是,JavaScript 是一门单线程语言,所以我们就可以得出:

海豚社区源码,vscode编辑md文档,Ubuntu装Snort,tomcat配置及安装,sqlite3复制表记录,学个爬虫编程需要多少钱一年,php 文库系统,福建正规seo服务电话,网站后台添加投票系统,运营工具模板lzw

JavaScript 是按照语句顺序执行的

易支付app源码,Ubuntu固定清理内存,tomcat6如何删除项目,Qt能写爬虫吗,php游戏币代理系统,网络宣传seolzw

首先看:

let a = 1console.log(a)let b = 2console.log(b)

这个显然大家都知道结果,依次输出1,2

然而换一种:

setTimeout(function() { console.log(1)})new Promise(function(resolve) { console.log(2) for(var i = 0;i< 10;i++){ i === 10 && resolve() }}).then(function() { console.log(3)})console.log(4)

这个时候再看代码的顺序执行,输出1,2, 3, 4。好了放到浏览器运行一下,什么?输出居然是 2, 4, 3,1。说好的按顺序执行呢?下面就需要去了解一下 JavaScript 的执行机制问题了。

单线程

首先JavaScript 是一门单线程的语言,在最新的HTML5 推出的 Web-worker,但是 JavaScript 是一个单线程的语言这一个核心还是没有改变。所以,JavaScript 的多线程都是基于单线程模拟出来的。所以牢记 JavaScript 是单线程语言。

事件循环

任务分为两类:

同步任务

异步任务

当我们打开页面时,页面的渲染就是一大堆同步任务,而像加载图片和音频资源耗时的任务,就是异步任务。时间循环的主要内容就是:

当任务进入执行栈的时候,判断是同步任务还是异步任务,如果是同步任务,进入主线程进行执行,异步进入 Event Table 进行注册函数。

当指定的事件完成后,Event Table 将这个函数移入到事件队列

主线程中的任务执行完毕后,去任务队列读取对应的函数,进入主线程执行

上述的过程不断重复,也就构成了事件循环

其中js引擎存在一个监控进程,不断检查主线程执行栈是否为空,一旦为空,就会去时间队列那检查有没有等待被调用的函数。

例如:

setTimeout( function() { console.log(1)}, 0)console.log(2)

首先 setTimeout进入Event Table

执行console.log(2)

setTimeout执行的函数进入事件队列

主线程从事件队列读取函数执行

这也就是为什么即使设置setTimeout(fn, 0)函数也不会立即执行的原因。不过即使主线程为空,0ms也是达不到的,根据HTML标准,最低是4ms。

setInterval

还有一个与setTimeout类似的函数,对于setInterval来说,是循环执行。对于执行顺序来说,setInterval会每隔指定的时间将注册的函数置入Event Queue,如果前面的任务耗时太久,那么同样需要等待。

但是需要注意的一点是,对于setInterval(fn, ms)来说,他并不是每过ms执行一次 ,而是每过ms会有fn进入任务队列。也就是说如果setInterval的回调函数的执行事件如果超过延迟ms,那么就看不出来事件间隔了。

Promise 和 process.nextTick(callback)

除了广义的同步任务和异步任务之外,还有对任务更精细的划分,分为:

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

micro-task(微任务):Promise、process.nextTick

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

用一段代码来说明:

setTimeout(function() { console.log(1);})new Promise(function(resolve) { console.log(2); resolve()}).then(function() { console.log(3);})console.log(4);

这段代码作为宏任务,开始第一次循环

先遇到setTimeout,那么它的回调函数进入到宏任务事件队列中

遇到Promise,Promise立即执行,输出2,then任务进入到微任务事件队列中

下面遇到console,输出4

第一个宏任务结束,看微任务事件队列,执行then,输出3

第一轮循环结束,看宏任务队列中存在setTimeout的回调函数执行,输出1

所有结果为:2,4,3,1

好了了解了基本的原理之后,我们来看一个更复杂的:

console.log(1);setTimeout(function() { console.log(2); process.nextTick(function() { console.log(3); }) new Promise(function(resolve) { console.log(4); resolve(); }).then(function() { console.log(5) })})process.nextTick(function() { console.log(6);})new Promise(function(resolve) { console.log(7); resolve();}).then(function() { console.log(8)})setTimeout(function() { console.log(9); process.nextTick(function() { console.log(10); }) new Promise(function(resolve) { console.log(11); resolve(); }).then(function() { console.log(12) })})

不知道大家答案是什么?接下来我们来进行分析一下:

第一轮:

首先整段代码作为一个宏任务进入主线程,首先遇到console.log()输出1

遇到第一个setTimeout()进入宏任务队列

遇到Process.nextTick()进入微任务队列

然后遇到Promise,立即执行,输出7,then被添加到微任务队列

遇到第二个setTimeout,进入宏任务队列

然后执行两个微任务

执行Process.nextTick()输出6

执行then,输出8

这样第一轮循环就彻底结束了,进行第二轮事件循环,也就是第一个setTimeout

首先遇到console.log(),输出2

遇到Process.nextTick(),进入微任务队列

遇到Promise立即执行输出4,then进入微任务队列

然后执行第一个微任务,输出3

执行then,输出5

这样第二轮事件循环就结束了,最后执行第二个setTimeout,第二个setTimeout和上面原理类似,也就不重复说明了。所以最终结果是:1,7,6,8,2,4,3,5,9,11,10,12

js执行机制实例详解

JavaScript运行机制之Event Loop

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。