JavaScript是单线程的,任务的执行时自上而下的,这就有了一个问题,当遇到一个比较耗时的任务时,下面的代码就会被阻塞,这就意味着卡死。所以js是有异步的,它的实现主要是通过事件循环(event loop)

事件循环

JavaScript中的任务分为两种:同步和异步

按照分类,当有任务执行时:

  •   判断是同步还是异步,同步进入主线程,异步进入event table
  •   异步任务在event table中注册函数,当满足触发条件,推入event queue
  •   同步任务进入主线程后一直执行,直到主线程空闲时,才会到event queue中查看是否有可执行的异步任务,如果有就推入到主线程中执行

以上三步循环执行,就是event loop

看这幅图

如:

        console.log("1")
setTimeout(function() {
console.log(2)
}, 1000)
console.log(3)
  • consloe.log(1),同步任务,进入主线程
  • setTimeout(),异步任务,进入event table,1秒后进入event queue里
  • console.log(3),同步任务,放入主线程
  • 先执行主线程中的任务,此时,主线程有,打印1,打印3
  • 当主线程执行结束,主线程空闲,于是,主线程到event queue(事件队列)里查看是否有可执行的函数,于是打印2

宏任务和微任务

除了之前说过的同步任务和异步任务,还有更精细的定义:

  • macro-task(宏任务):包含整体代码script,setTimeout,setlnterval
  • micro-task(微任务):Promise,process.nextTick

不同的任务会进入不同的event queue,比如setTimeout,setlnterval会进入相同的event queue,Promise,process.nextTick会进入相同的event queue

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

        console.log("start")
setTimeout(function(){
console.log("setTimeout")
},0) new Promise(function(resolve){
          resolve()
console.log("promise")
}).then(function(){
console.log("then")
}) console.log("end")

  先按照最开始的方式解释,及同步任务和异步任务

  • console.log("start"),同步任务,进入主线程,直接打印
  • setTimeout,异步任务,进入event table
  • Promise,同步任务,进入主线程,直接打印
  • then,异步,放入event table
  • console.log("end")同步任务,直接打印
  • 结束,先执行主线程的任务,start => promise => end ,主线程结束,查看任务队列中是否有待执行的任务,打印 setTimeout => then
  • 即,start => promisr => end =>  setTimeout => then

然而执行的结果却是这样的:start => promisr => end =>  then => setTimeout

所以我们要同过宏任务和微任务的方式解释

  • 首先执行script下的宏任务,遇到console.log("start"),直接打印 “start”
  • 遇到setTimeout,将其放入宏任务队列
  • 遇到promise,直接执行,打印 “promise”
  • 遇到then,微任务,放入微任务队列
  • 遇到console.log("end"),直接打印 “end”
  • 此时,整体script作为第一个宏任务执行结束,看看有没有微任务,发现有个then在微任务的event queue中,执行,打印“then”
  • 到此第一轮事件循环结束,开始第二轮事件循环,当然要从宏任务event queue开始,此时宏任务event queue中有setTimeout,立即执行,打印“setTimeout”
  • 结束,此时的顺序start => promisr => end =>  then => setTimeout

来看关系图

最后

  要知道js是一门单线程语言,所有实现异步的方式,其实都是用同步模拟出来的,而事件循环event loop 是实现异步的一种方法,也是js的执行机制

JavaScript的执行机制的更多相关文章

  1. javaScript的执行机制-同步任务-异步任务-微任务-宏任务

    一.概念理解 1.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变.所以一切javascr ...

  2. javascript的执行机制—Event Loop

    既然今天要谈的是javascript的事件循环机制,要理解事件循环,首先要知道事件循环是什么. 我们先从一个例子来看一下javascript的执行顺序. <script> setTimeo ...

  3. 一段代码说明javascript闭包执行机制

    假设你能理解以下代码的执行结果,应该就算理解闭包的执行机制了. var name = "tom"; var myobj = { name: "jackson", ...

  4. JavaScript 的执行机制

    一.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web Worker,但javascript是单线程这一核心仍未改变. 为什么js是单线程的语言?因为最初 ...

  5. javascript执行机制

    文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的 ...

  6. 彻底弄懂 JavaScript 执行机制

    本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定 ...

  7. JavaScript 执行机制

    一.宏任务与微任务 macro-task(宏任务):包括整体代码script,setTimeout,setInterval micro-task(微任务):Promise,process.nextTi ...

  8. 转载---JavaScript执行机制

    很好的一篇文章,原地址 JavaScript执行机制 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不 ...

  9. 【js】javaScript 执行机制

    javascript 是一门单线程语言(按照语句一行一行的执行) let a = '1'; console.log(a); let b = '2'; console.log(b); 这样子正常执行是没 ...

随机推荐

  1. fireFox在中国的https网站的时候,老会出 ssl_error_unsupported_version 这个错误。

    fireFox在中国的https网站的时候,老会出 ssl_error_unsupported_version  这个错误. 出现在 这个的解决办法就是 在地址栏里输入 about:config 查找 ...

  2. rails 里js 在production 只合并不压缩等问题,以及assets pipeline 加载js 在指定页面上

    因为刚学rails,试着做了一个小系统操作微信公共帐号, 之后部署的时候遇见了一个问题,整套系统在互联网端访问,非常的慢,而在手机端访问,10s后才会有响应, 打开chrome的调试工具,发现appl ...

  3. ajax的serialize()方法

    自己看吧,超级简单,就不用挨个获取表单名称和值对装在Json里往php传了,直接传个form就可以. [HTML] <form method="post" id=" ...

  4. HDU 5336——XYZ and Drops——————【广搜BFS】

    XYZ and Drops Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  5. Winform窗体“空闲事件”

    Application.Idle += Application_Idle; void Application_Idle(object sender, EventArgs e){ } 当应用程序完成处理 ...

  6. 云计算&大数据相关知识

    1.极客学院云计算&大数据总链接:http://wiki.jikexueyuan.com/list/cloud/ 一.NSQ相关参考资料: 1.极客学院NSQ指南:http://wiki.ji ...

  7. Jquery 客户端验证

    Jquery 客户端验证 //引入js文件 validate.js <html> <head> <title>jqueryValidateDemo</titl ...

  8. JavaScript 数组(Array)

    //声明方式 //调用 Array构造函数创建并赋值 var users = new Array(); //new 可以省略 ); //new 可以省略 var users3 = new Array( ...

  9. hdu 4123 树形DP+单调队列

    http://acm.hust.edu.cn/vjudge/problem/25790 这题基本同poj 3162 要注意mx,mx2,vx,vx2每次都要初始化 #include <iostr ...

  10. BZOJ4260: Codechef REBXOR (01Tire树)

    题意 题目链接 Sol 首先维护出前缀xor和后缀xor 对每个位置的元素插入到Trie树里面,每次找到和该前缀xor起来最大的元素 正反各做一遍,取最大. 记得要开log倍空间qwq.. #incl ...