之前我们一直说要介绍下前端的知识点,一直没空总结,这不来了;
创新互联主要从事成都网站设计、做网站、网页设计、企业做网站、公司建网站等业务。立足成都服务堆龙德庆,十年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
js运行机制,来一篇总结
如果JS中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验;
既然JS是单线程的,只能在一条线程上执行,又是如何实现的异步呢?
是通过的事件循环(event loop),理解了event loop机制,就理解了JS的执行机制。
你是否觉得同步异步的执行机制流程就是JavaScript执行机制的全部?不是的,JavaScript除了广义上的的同步任务何异步任务,其对任务还有更精细的定义:
不同类型的任务会进入对应的Event Queue。
事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。
3.1、同步
- console.log(1);
- console.log(2);
- console.log(3);
- /*
- 执行结果:1、2、3
- 同步任务,按照顺序一步一步执行
- */
3.2、同步和异步
- console.log(1);
- setTimeout(function() {
- console.log(2);
- },1000)
- console.log(3);
- /*
- 执行结果:1、3、2
- 同步任务,按照顺序一步一步执行
- 异步任务,放入消息队列中,等待同步任务执行结束,读取消息队列执行
- */
3.3、异步任务进一步分析
- console.log(1);
- setTimeout(function() {
- console.log(2);
- },1000)
- setTimeout(function() {
- console.log(3);
- },0)
- console.log(4);
- /*
- 猜测是:1、4、2、3 但实际上是:1、4、3、2
- 分析:
- 同步任务,按照顺序一步一步执行
- 异步任务,当读取到异步任务的时候,将异步任务放置到Event table(事件表格)
- 中,当满足某种条件或者说指定事情完成了(这里的是时间分别是达到了0ms和1000ms)当指定
- 事件完成了才从Event table中注册到Event Queue(事件队列),当同步事件完成了,便从
- Event Queue中读取事件执行。(因为3的事情先完成了,所以先从Event table中注册到
- Event Queue中,所以先执行的是3而不是在前面的2)
- */
3.4、宏任务和微任务
- console.log(1);
- setTimeout(function() {
- console.log(2)
- },1000);
- new Promise(function(resolve) {
- console.log(3);
- resolve();
- }
- ).then(function() {
- console.log(4)
- });
- console.log(5);
- /*
- 以同步异步的方式来判断的结果应该是:1、3、5、2、4
- 但是事实上结果是:1、3、5、4、2
- 为什么是这样呢?因为以同步异步的方式来解释执行机制是不准确的,更加准确的方式是宏任务和微任务:
- 因此执行机制便为:执行宏任务 ===> 执行微任务 ===> 执行另一个宏任务 ===> 不断循环
- 即:在一个事件循环中,执行第一个宏任务,宏任务执行结束,执行当前事件循环中的微任务,
- 执行完毕之后进入下一个事件循环中,或者说执行下一个宏任务
- */
3.5、是否彻底理解JavaScript执行机制实例
- 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')
- })
- })
- /*
- 1、 第一轮事件循环流程分析如下:
- 整体script作为第一个宏任务进入主线程,遇到console.log,输出1。
- 遇到setTimeout,其回调函数被分发到宏任务Event Queue中。我们暂且记为setTimeout1。
- 遇到process.nextTick(),其回调函数被分发到微任务Event Queue中。我们记为process1。
- 遇到Promise,new Promise直接执行,输出7。then被分发到微任务Event Queue中。我们记为then1。
- 又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为setTimeout2。
- 宏任务Event Queue 微任务Event Queue
- setTimeout1 process1
- setTimeout2 then1
- 上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。
- 我们发现了process1和then1两个微任务。
- 执行process1,输出6。
- 执行then1,输出8。
- 好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。
- 2、 那么第二轮时间循环从setTimeout1宏任务开始:
- 首先输出2。接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中,
- 记为process2。new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2。
- 宏任务Event Queue 微任务Event Queue
- setTimeout2 process2
- then2
- 第二轮事件循环宏任务结束,我们发现有process2和then2两个微任务可以执行。
- 输出3。
- 输出5。
- 第二轮事件循环结束,第二轮输出2,4,3,5。
- 3、 第三轮事件循环开始,此时只剩setTimeout2了,执行。
- 直接输出9。
- 将process.nextTick()分发到微任务Event Queue中。记为process3。
- 直接执行new Promise,输出11。
- 将then分发到微任务Event Queue中,记为then3。
- 宏任务Event Queue 微任务Event Queue
- process3
- then3
- 第三轮事件循环宏任务执行结束,执行两个微任务process3和then3。
- 输出10。
- 输出12。
- 第三轮事件循环结束,第三轮输出9,11,10,12。
- 整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。
- */
javascript是一门单线程语言;
Event Loop是javascript的执行机制;
客户端也是要学习前端语言的,以后我们会讲解一些前端的知识点
本文转载自微信公众号「Android开发编程」
网站标题:前端进阶之JS运行原理和机制详解
URL标题:http://www.shufengxianlan.com/qtweb/news39/543189.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联