资讯专栏INFORMATION COLUMN

浏览器端Event loop简介

alexnevsky / 1394人阅读

摘要:所以提出了标准,允许创建子线程,但是规定很严格,子线程要受到主线程控制,并且不能操作,这种折中方法使得更加灵活了。案例输出的结果为案例这个的执行结果都是一样的,都会先执行事件,因为要等主线程空了才会去查看子线程有没有回调内容。

了解过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先执行了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82277.html

相关文章

  • 览器与Node的事件循环(Event Loop)有何区别?

    摘要:事件触发线程主要负责将准备好的事件交给引擎线程执行。它将不同的任务分配给不同的线程,形成一个事件循环,以异步的方式将任务的执行结果返回给引擎。 Fundebug经作者浪里行舟授权首发,未经同意请勿转载。 前言 本文我们将会介绍 JS 实现异步的原理,并且了解了在浏览器和 Node 中 Event Loop 其实是不相同的。 一、线程与进程 1. 概念 我们经常说 JS 是单线程执行的,...

    TANKING 评论0 收藏0
  • Python 的异步 IO:Asyncio 简介

    摘要:是并发的一种方式。并不能带来真正的并行。可交给执行的任务,称为协程。输出等待三秒钟程序退出现在改用输出等待三秒钟程序没有退出三秒钟过后,结束,但是程序并不会退出。但是如果关闭了,就不能再运行了此处异常建议调用,以彻底清理对象防止误用。 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知。 Asyncio 是并发(concurr...

    ky0ncheng 评论0 收藏0
  • 2018你成长了么?一份给你的前技术清单

    摘要:由于个人精力有限,一些技术点的归纳可能有失偏颇,或者目前并未纳入进来,因此上的清单内容也会不断更新。 2018 眼看就要过去了,今年的你相较去年技术上有怎样的收获呢? 记得年初的时候我给自己制定了一个学习计划,现在回顾来看完成度还不错。但仍有些遗憾,一些技术点没有时间去好好学习。 在学习中我发现,像文章这样的知识往往是碎片化的,而前端涉及到的面很多,如果不将这些知识有效梳理,则无法形成...

    K_B_Z 评论0 收藏0
  • 2018你成长了么?一份给你的前技术清单

    摘要:由于个人精力有限,一些技术点的归纳可能有失偏颇,或者目前并未纳入进来,因此上的清单内容也会不断更新。 2018 眼看就要过去了,今年的你相较去年技术上有怎样的收获呢? 记得年初的时候我给自己制定了一个学习计划,现在回顾来看完成度还不错。但仍有些遗憾,一些技术点没有时间去好好学习。 在学习中我发现,像文章这样的知识往往是碎片化的,而前端涉及到的面很多,如果不将这些知识有效梳理,则无法形成...

    LancerComet 评论0 收藏0
  • 2018你成长了么?一份给你的前技术清单

    摘要:由于个人精力有限,一些技术点的归纳可能有失偏颇,或者目前并未纳入进来,因此上的清单内容也会不断更新。 2018 眼看就要过去了,今年的你相较去年技术上有怎样的收获呢? 记得年初的时候我给自己制定了一个学习计划,现在回顾来看完成度还不错。但仍有些遗憾,一些技术点没有时间去好好学习。 在学习中我发现,像文章这样的知识往往是碎片化的,而前端涉及到的面很多,如果不将这些知识有效梳理,则无法形成...

    Flands 评论0 收藏0

发表评论

0条评论

alexnevsky

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<