博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浏览器端Event loop简介
阅读量:5966 次
发布时间:2019-06-19

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

了解过javascript的都知道其最大的特点就是单线程,也就是说同一时间只能干一件事情。那么为什么不能是多线程呢?原因很简单,多线程太复杂了,假设javascript有2个线程,一个去添加dom,一个去删除dom,那么浏览器就懵逼了,这到底要我选择哪个?所以为了避免不必要的麻烦,javascript一开始就选择了单线程。但是单线程也有问题,假设有个任务是要向服务器去请求一个文件,如果这个文件很大,那么就不能立即执行下一语句(要等到文件回来),这样就造成了浏览器假死的现象。所以html5提出了web worker标准,允许javascript创建子线程,但是规定很严格,子线程要受到主线程控制,并且不能操作dom,这种折中方法使得javascript更加灵活了。

到目前为止javascript可以有子线程了,这时候再遇到像之前提到的如果一个io操作很费时间,那么就可以把这个任务挂起来,等返回结果了再来执行这个任务。于是所有的任务都变成了2种,一种是同步任务(从上到下一步一步执行),另外一种就是异步任务(等有结果了再执行,即所谓的消息队列)。这2种任务进入到线程也不一样,同步的从上到下依次直接进入主线程形成执行栈,异步的等有返回结果了,比如ajax请求成功了,就把成功的回调放到子线程里面去(失败就把失败的回调放到子线程里面去)。现在浏览器开始执行主线程里面的执行栈了,等主线程里面的执行栈都执行完毕了,主线程就会到子线程里面去看之前挂起到任务哪些有回调了,如果有回调了,那就把该回调内容放到主线程里面去执行,等执行完毕了再去子线程看有没有新的回调了(这里要注意的是主线程全部执行完毕,才会去子线程去看),主线程不断的重复这个步骤,这就是所谓的Event loop,也就是javascript的运行机制。比较特殊的是setTimeout,setinterval这2个方法,它们也会被放倒子线程里面去,比如我使用setTimeout(fn,3000),有时候不一定是3s之后会执行fn这个事件,还要看主线程里面的任务是否完成。

案例1:

function f() {  console.log("foo");  setTimeout(g, 0);  console.log("baz");  h();}function g() {  console.log("bar");}function h() {  console.log("blix");}f();输出的结果为:foo 、baz 、 blix 、bar

案例2 :

var req = new XMLHttpRequest();req.open('GET', url);    req.onload = function (){};    req.onerror = function (){};    req.send();var req = new XMLHttpRequest();req.open('GET', url);req.send();req.onload = function (){};    req.onerror = function (){};

这2个的执行结果都是一样的,都会先执行onload事件,因为javascript要等主线程空了才会去查看子线程有没有回调内容。

注意点:

异步的任务执行的顺序是不固定的,主要看返回的速度,假设a任务写在b任务之前,但是a任务比较大,耗时比较长,而b任务耗时短,那么b任务有了回调先会进入到子线程里面,这样会被主线程先轮询到,但是也有可能b任务网络不好,a任务先返回了,那么a任务的回调先被注册到子线程了,导致a先执行了。

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

你可能感兴趣的文章
设置Eclipse编码方式
查看>>
分布式系统唯一ID生成方案汇总【转】
查看>>
并查集hdu1232
查看>>
Mysql 监视工具
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
博客搬家了
查看>>
Python中使用ElementTree解析xml
查看>>
jquery 操作iframe、frameset
查看>>
解决vim中不能使用小键盘
查看>>
jenkins权限管理,实现不同用户组显示对应视图views中不同的jobs
查看>>
我的友情链接
查看>>
批量删除用户--Shell脚本
查看>>
Eclipse Java @Override 报错
查看>>
知道双字节码, 如何获取汉字 - 回复 "pinezhou" 的问题
查看>>
Python高效编程技巧
查看>>
js中var self=this的解释
查看>>
Facebook 接入之获取各个配置参数
查看>>
linux的日志服务器关于屏蔽一些关键字的方法
查看>>
事情的两面性
查看>>