博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS事件循环EventLoop初探
阅读量:6262 次
发布时间:2019-06-22

本文共 1813 字,大约阅读时间需要 6 分钟。

概念

js是基于单线程运行的,而一些特定事件又是异步执行的,所以这种单线程+异步的执行方式一定是事件驱动的 而一般浏览器环境下有这样几种线程。

js引擎线程 (解释执行js代码、用户输入、网络请求)主线程

GUI线程 (绘制用户界面、与js主线程是互斥的)先绘制dom再绘制css

http网络请求线程 (处理用户的get、post等请求,等返回结果后将回调函数推入任务队列)

定时触发器线程 (setTimeout、setInterval等待时间结束后把执行函数推入任务队列中)

浏览器事件处理线程(将click、mouse等交互事件发生后将这些事件放入事件队列中)

上一张经典的eventLoop图,了解几个基本概念

1,栈(stack):队列优先,由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2.堆(heap):先进后出;动态分配的空间
JavaScript中的变量分为基本类型和引用类型。基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象
这里引入一个概念(图上没有),就是js中的task和microTask 一般来讲,我们把setTimeout,setInterval,浏览器的dom操作,用户点击等交互事件归结为task,而Promise callback Mutation callback还有nextTick我们归结为microTask,

那问题就来了,js中task和microTask执行顺序是怎样的

由于js是单线程,所有的多线程任务最后都要压入主线程执行栈去执行,如图所示,task会放入回调队列里 由eventLoop取出依次执行。

这里可以解释一个小问题,如果多个setTimeout的情况下,执行时间不是特别的精确,setTimeout 它会在延迟时间结束后分配一个新的 task 至 event loop 中,而不是立即执行,所以 setTimeout 的回调函数会等待前面的 task 都执行结束后再运行。

说到这里好像还没有microTask什么事,那microTask在什么时候执行呢,通俗的说,你可以将microTask理解为一个爱插队的大妈,就是在一个task事件结束后,microTask就插入执行栈立即执行,执行顺序是主线程执行栈的队尾插入,callback quene之前

上一段代码吧,来直观的了解一下执行顺序

console.log('start');   setTimeout(function() {    console.log('setTimeout1');        setTimeout(function() {           console.log('setTimeout2');       },0);    console.log('setTimeout3');  }, 0);    Promise.resolve().then(function() {    console.log('promise1');  }).then(function() {   console.log('promise2'); });  console.log('end');复制代码

最后结果是 1,start 2,end 3,promise1 4,promise2 5,setTimeout1,6,setTimeout3 6,setTimeout2

顺序是,先执行打印start 然后打印edn 这时候microTask (promise)插队进入 打印promise1,promise2, 然后执行setTimeout打印setTimeout1,setTimeout3,这里可以看做

console.log('setTimeout1');
console.log('setTimeout3');
这两句一起压入执行栈,

setTimeout(function() {        console.log('setTimeout2');},0);复制代码

进入task队列,由EventLoop取出,所以最后执行顺序是

1,start 2,end 3,promise1 4,promise2 5,setTimeout1,6,setTimeout3 6,setTimeout2

转载地址:http://gfkpa.baihongyu.com/

你可能感兴趣的文章
图片裁剪和异步上传插件--一步到位(记录)
查看>>
在Vs2012 中使用SQL Server 2012 Express LocalDB打开Sqlserver2012数据库
查看>>
【分享】博客美化(7)推荐几个优秀的自定义博客
查看>>
人工智能和机器学习领域的一些有趣的开源项目
查看>>
python sorted排序
查看>>
python中xrange和range的异同
查看>>
PHP根据ASCII码返回具体的字符
查看>>
atitit.系统架构图 的设计 与工具 attilax总结
查看>>
URAL 1774 A - Barber of the Army of Mages 最大流
查看>>
处理器(CPU)调度问题
查看>>
leetcode - 位运算题目汇总(下)
查看>>
多少个矩形被覆盖
查看>>
22、ASP.NET MVC入门到精通——搭建项目框架
查看>>
3-7 类的友元函数的应用
查看>>
IntelliJ IDEA安装 一些配置
查看>>
【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
查看>>
post请求和get请求
查看>>
零成本实现接口自动化测试 – Java+TestNG 测试Restful service
查看>>
源码安装php时出现Sorry, I cannot run apxs. Possible reasons follow:
查看>>
使用T4模板生成POCO类
查看>>