上篇讲异步的时候,提到了同步队列和异步队列的说法,其实只是一种形象的称呼,分别代表主线程中的任务和任务队列中的任务,那么此篇我们就来详细探讨这两者。

一、来张图感受一下

如果看完觉得一脸懵逼,请继续往下看。

二、解析

我们还是拿上篇的例子做解析

step1:f1、Promise对象实例化、f2被放入主线程的堆内存中;

step2:Promise对象实例化后的同步代码块被放入主线程的执行栈中执行,并且产生的异步任务被放入任务队列;

step3:f1被放入主线程的执行栈中执行(打印“我是F1”),for循环产生的1000个定时器(异步任务)放入任务队列;

step4:f2被放入主线程的执行栈中执行,连续5次;

step5:至此,主线程的执行栈中已经没有任务了,于是事件循环(event loop)机制从任务队列中取出一个任务放入主线程的执行栈中执行;

step6:等待主线程的执行栈中又没有任务了,事件循环机制再次去任务队列中取出任务;

step7:重复第6步。

 三、任务队列

上面提到了任务队列,任务队列就是等候执行的一系列任务,就好比锅里的饭,你只有把碗里的饭吃完了,才能再次去锅里再盛一碗(不要杠!);

只有主线程的执行栈中没有了任务,事件循环机制才会去任务队列拿任务去执行。

由刚开始的图,你也看到了,任务队列是分不同类别并且是有优先级的。

  • 任务队列又分为macro-task(宏任务)和micro-task(微任务);
  • macro-task大概包括:script(整体代码),setTimeout,setInterval,setImmediate,I/O,UI rendering;
  • micro-task大概包括:process.nextTick,Promise,Object.observe(已废弃),MutationObserver(html5新特性)
  • setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的具体执行任务。
  • 来自不同任务源的任务会进入到不同的任务队列

优先级的话,micro-task > macro-task;

对于micro-task:process.nextTick > Promise.then

对于macro-task:setTimeout > setImmediate

具体的案例演示,请参照这篇文章:事件循环的顺序(优先级)
四、简单demo带你理解事件循环
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},)
}) setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},)

step1:

分析:开始任务队列里有微任务promise1和宏任务timeout1,第一次事件循环一看有微任务,二话不说,直接拿promise1到主线程跑(其实是跑完所有的微任务);promise1运行结果是,控制台打印promise1,并生成一个宏任务timeout2。

step2:

分析:因为此时任务队列里只有宏任务,于是,根据队列规则以及优先级(这里只有一种宏任务,所以没有涉及到优先级),事件循环拿timeout1去主线程跑;

timeout1运行结果,打印setTimeout1,并生成一个微任务promise2,至此第一次事件循环结束。

step3:

分析:任务队列里有微任务promise2和宏任务timeout2,事件循环一看有微任务,二话不说,直接拿promise2到主线程跑;

运行结果,控制台打印promise2,此时任务队列只剩下一个宏任务timeout2。

step4:

分析:此时任务队列只有一个宏任务timeout2,事件循环二话不说,因为没得挑了嘛,直接拿到主线程去跑,控制台打印timeout2,至此结束,也是第二次事件循环结束。

所以,一次事件循环是跑完所有微任务并推一个宏任务到主线程的过程。

最新文章

  1. 慎重管理SQL Server服务的登录(启动)账户和密码
  2. IOS第11天(1:UIPickerView点餐)
  3. swift 如何删除subviews
  4. USB做Host的OTG原理
  5. mybatis03
  6. CodeIgniter框架介绍
  7. CentOS6.7 下安装git
  8. Which PHP mode? Apache vs CGI vs FastCGI
  9. CSS前端开发学习总结、一
  10. ASP.NET自定义处理程序
  11. [笔记]机器学习(Machine Learning) - 02.逻辑回归(Logistic Regression)
  12. 微信支付——openid获取不到
  13. C#EF中,使用类似于SQL中的% 模糊查询
  14. C++ bitset 用法
  15. [再寄小读者之数学篇](2014-05-27 矩阵的迹与 Jacobian)
  16. 有哪些api接口可以实现微信自动唤醒浏览器,下载app,打开网页
  17. MySQL中MyISAM与InnoDB区别及选择(转)
  18. loadrunner 脚本开发-url解码
  19. 文件权限控制--umask
  20. [z]重建索引

热门文章

  1. 20145329《Java程序设计》第六周学习总结
  2. 20145231熊梓宏 《网络对抗》 实验9 Web安全基础实践
  3. delegate委托
  4. JS 如何获取当前上一个月、下一个月和月份所含天数
  5. Python学习札记(十一) Function2 函数定义
  6. MAC OS 命令行使用详解【转】
  7. hdu 4602 Partition 矩阵快速幂
  8. jQuery实际案例⑥——图片跟随鼠标、五角星评分案例
  9. ubuntu14.04安装hadoop2.6.0(伪分布模式)
  10. JSP 异常处理