首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

对浏览器端javaScript运行机制的理解

线程

同步异步

Event-Loop

线程

Javascript语言的执行环境是"单线程"(single thread)。

所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。而Javascript运行在浏览器上,然而浏览器内核是多线程的,它包含以下几个线程:

GUI 渲染线程

JavaScript引擎线程

定时触发器线程

事件触发线程

异步http请求线程

我们平时使用到最多的就是GUI 渲染线程,JavaScript引擎线程,异步http请求线程。

同步异步

浏览器端能够异步主要还是因为Event-Loop这个默默的在幕后执行。

1.同步

同步,也就是JavaScript在执行的时候是按照顺序执行,前一个任务执行完毕之后才会执行下一个任务。因此当遇到比较耗时的任务时,就是使得后边的任务长时间的等待,例如当浏览器端执行一段耗时js代码,就会使得浏览器假死。因此对于这种情况就需要将耗时的任务异步执行,不阻塞其他非耗时任务的执行。

2.异步

异步,简单说就是,将耗时任务放入其他线程执行,主线成会在将来的某个时刻收到回调通知。

浏览器端的异步方式:

- 回调函数

这是异步编程最基本的方法。

假定有两个函数f1和f2,后者等待前者的执行结果。

如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。

执行代码就变成下面这样:

采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。

回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。

- 事件监听

另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

还是以f1和f2为例。首先,为f1绑定一个事件(这里采用的jQuery的写法)。

上面这行代码的意思是,当f1发生done事件,就执行f2。然后,对f1进行改写:

f1.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行f2。

这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰

- Promises对象

Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。

简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。

但是Promise一旦执行,不可取消。

Event-Loop

一张图来看一下

JavaScript引擎的内部运行机制跟Event loop没有任何的关系。

event loops隐藏得比较深,很多人对它很陌生。但提起异步,相信每个人都知道。异步背后的“靠山”就是event loops。这里的异步准确的说应该叫浏览器的event loops或者说是javaScript运行环境的event loops,因为ECMAScript中没有event loops,event loops是在HTML Standard定义的。

总结一点就是,除了js引擎线程外的其他线程在执行完任务后都会将结果加入到Event-Loop的任务队列中,只有当js引擎线程将当前任务执行完后才会去继续执行Event-Loop的任务队列的任务。

写在最后

最近经常有很多程序员朋友问我有没有什么学习资料,尤其是前端还有php的。因为本人是学全栈的,所以手里是有一些前端还有PHP全套视频学习资料。这些资料绝对比那些在群里漫天飞的资料强多了。相信看完这些,你绝对可以找到一份好工作!

为了感谢大家的支持,今天我在这里统一说下吧:

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180110A0CYQ100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券