前端进阶之JS运行原理和机制详解

前言

之前我们一直说要介绍下前端的知识点,一直没空总结,这不来了;

创新互联主要从事成都网站设计、做网站、网页设计、企业做网站、公司建网站等业务。立足成都服务堆龙德庆,十年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575

js运行机制,来一篇总结

一、js的基础知识点介绍

二、相关概念

1、JS为什么是单线程的?

2、JS为什么需要异步?

如果JS中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验;

3、JS单线程又是如何实现异步的呢?

既然JS是单线程的,只能在一条线程上执行,又是如何实现的异步呢?

是通过的事件循环(event loop),理解了event loop机制,就理解了JS的执行机制。

4、任务队列

5、Event Loop

6、setTimeout(fn,0)

三、js执行机制介绍

1、javascript的同步和异步

2、JavaScript的宏任务与微任务

你是否觉得同步异步的执行机制流程就是JavaScript执行机制的全部?不是的,JavaScript除了广义上的的同步任务何异步任务,其对任务还有更精细的定义:

不同类型的任务会进入对应的Event Queue。

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

3、实例来说明JavaScript的执行机制

3.1、同步

 
 
 
 
  1. console.log(1); 
  2. console.log(2); 
  3. console.log(3); 
  4. /* 
  5.     执行结果:1、2、3 
  6.     同步任务,按照顺序一步一步执行 
  7. */ 

3.2、同步和异步

 
 
 
 
  1. console.log(1); 
  2. setTimeout(function() { 
  3.     console.log(2); 
  4. },1000) 
  5. console.log(3); 
  6. /* 
  7.     执行结果:1、3、2 
  8.     同步任务,按照顺序一步一步执行 
  9.     异步任务,放入消息队列中,等待同步任务执行结束,读取消息队列执行 
  10. */ 

3.3、异步任务进一步分析

 
 
 
 
  1. console.log(1); 
  2. setTimeout(function() { 
  3.     console.log(2); 
  4. },1000) 
  5. setTimeout(function() { 
  6.     console.log(3); 
  7. },0) 
  8. console.log(4); 
  9. /* 
  10.     猜测是:1、4、2、3   但实际上是:1、4、3、2 
  11.     分析: 
  12.         同步任务,按照顺序一步一步执行 
  13.         异步任务,当读取到异步任务的时候,将异步任务放置到Event table(事件表格) 
  14. 中,当满足某种条件或者说指定事情完成了(这里的是时间分别是达到了0ms和1000ms)当指定 
  15. 事件完成了才从Event table中注册到Event Queue(事件队列),当同步事件完成了,便从 
  16. Event Queue中读取事件执行。(因为3的事情先完成了,所以先从Event table中注册到 
  17. Event Queue中,所以先执行的是3而不是在前面的2) 
  18. */ 

3.4、宏任务和微任务

 
 
 
 
  1. console.log(1); 
  2. setTimeout(function() { 
  3.     console.log(2) 
  4. },1000); 
  5. new Promise(function(resolve) { 
  6.     console.log(3); 
  7.     resolve(); 
  8. ).then(function() { 
  9.     console.log(4) 
  10. }); 
  11. console.log(5); 
  12. /* 
  13.     以同步异步的方式来判断的结果应该是:1、3、5、2、4 
  14.     但是事实上结果是:1、3、5、4、2 
  15.     为什么是这样呢?因为以同步异步的方式来解释执行机制是不准确的,更加准确的方式是宏任务和微任务: 
  16.     因此执行机制便为:执行宏任务 ===> 执行微任务 ===> 执行另一个宏任务 ===> 不断循环 
  17.         即:在一个事件循环中,执行第一个宏任务,宏任务执行结束,执行当前事件循环中的微任务, 
  18. 执行完毕之后进入下一个事件循环中,或者说执行下一个宏任务 
  19. */ 

3.5、是否彻底理解JavaScript执行机制实例

 
 
 
 
  1. console.log('1'); 
  2. setTimeout(function() { 
  3.     console.log('2'); 
  4.     process.nextTick(function() { 
  5.         console.log('3'); 
  6.     }) 
  7.     new Promise(function(resolve) { 
  8.         console.log('4'); 
  9.         resolve(); 
  10.     }).then(function() { 
  11.         console.log('5') 
  12.     }) 
  13. }) 
  14. process.nextTick(function() { 
  15.     console.log('6'); 
  16. }) 
  17. new Promise(function(resolve) { 
  18.     console.log('7'); 
  19.     resolve(); 
  20. }).then(function() { 
  21.     console.log('8') 
  22. }) 
  23. setTimeout(function() { 
  24.     console.log('9'); 
  25.     process.nextTick(function() { 
  26.         console.log('10'); 
  27.     }) 
  28.     new Promise(function(resolve) { 
  29.         console.log('11'); 
  30.         resolve(); 
  31.     }).then(function() { 
  32.         console.log('12') 
  33.     }) 
  34. }) 
  35. /* 
  36. 1、 第一轮事件循环流程分析如下: 
  37.     整体script作为第一个宏任务进入主线程,遇到console.log,输出1。 
  38.     遇到setTimeout,其回调函数被分发到宏任务Event Queue中。我们暂且记为setTimeout1。 
  39.     遇到process.nextTick(),其回调函数被分发到微任务Event Queue中。我们记为process1。 
  40.     遇到Promise,new Promise直接执行,输出7。then被分发到微任务Event Queue中。我们记为then1。 
  41.     又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为setTimeout2。 
  42.     宏任务Event Queue   微任务Event Queue 
  43.     setTimeout1         process1 
  44.     setTimeout2         then1 
  45.     上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。 
  46.     我们发现了process1和then1两个微任务。 
  47.     执行process1,输出6。 
  48.     执行then1,输出8。 
  49.     好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。 
  50. 2、 那么第二轮时间循环从setTimeout1宏任务开始: 
  51.     首先输出2。接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中, 
  52. 记为process2。new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2。 
  53.     宏任务Event Queue     微任务Event Queue 
  54.     setTimeout2           process2 
  55.                           then2 
  56.     第二轮事件循环宏任务结束,我们发现有process2和then2两个微任务可以执行。 
  57.         输出3。 
  58.         输出5。 
  59.         第二轮事件循环结束,第二轮输出2,4,3,5。 
  60. 3、 第三轮事件循环开始,此时只剩setTimeout2了,执行。 
  61.         直接输出9。 
  62.         将process.nextTick()分发到微任务Event Queue中。记为process3。 
  63.         直接执行new Promise,输出11。 
  64.         将then分发到微任务Event Queue中,记为then3。 
  65.     宏任务Event Queue     微任务Event Queue 
  66.                             process3 
  67.                             then3      
  68.     第三轮事件循环宏任务执行结束,执行两个微任务process3和then3。 
  69.         输出10。 
  70.         输出12。 
  71.         第三轮事件循环结束,第三轮输出9,11,10,12。 
  72.     整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。 
  73. */ 

总结

javascript是一门单线程语言;

Event Loop是javascript的执行机制;

客户端也是要学习前端语言的,以后我们会讲解一些前端的知识点

本文转载自微信公众号「Android开发编程」


网站题目:前端进阶之JS运行原理和机制详解
文章转载:http://www.turtgq.com/article/dpgdddd.html

其他资讯