JavaScript的单线程和异步

版权声明:转载需注明出处 https://blog.csdn.net/zf2014122891/article/details/85539386

前言

我们都知道JavaScript是单线程语言,但有没有想过JavaScript为什么是单线程语言,而不采用效率更高的多线程呢?并且一个单线程语言又是如何能够实现异步操作的呢?接下来我们详细讨论JavaScript的单线程和异步实现(注:理论层面的实现,非语言层面)。

1、 JavaScript的单线程

众所周知,JavaScript是单线程语言,试想一下,如果面试官问你JavaScript为什么是单线程,你会怎样回答?

我们首先要知道JavaScript是浏览器脚本语言,是用来和用户交互并且操作DOM的。试想一个场景,有两个线程,一个线程向DOM节点中添加内容,另一个线程将此节点删除,这样就会导致很多不可预测的事情。所以,JavaScript的用途也就是应用场景决定了它必须是单线程。

在HTML5中,为了利用多核cpu的计算能力,提出了新的标准,允许JavaScript脚本创建多个线程,但是子线程必须受主线程的控制,并且不得操作DOM,所以这个标准并没有改变JavaScript是单线程的本质。

2、 JavaScript的异步实现

首先我们要明白,为什么需要异步。

所谓单线程,就必然意味着:所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。然而排队往往不是因为我们的CPU计算能力不行(如果是,我们也只好认了),大多数情况下,CPU处于空闲状态,而IO操作是非常慢的一件事情(比如网络请求,定时器和事件监听等等),我们不得不等到结果出来才能执行下一个任务。

可能有很多朋友到这里就迷惑了,既然JavaScript是单线程语言,他怎么能够实现异步呢?这是因为JavaScript的单线程是负责JavaScript解释执行的引擎主线程是单线程的单线程和异步不可能同时成为一个语言的特点),但是JavaScript所依赖的宿主环境(比如浏览器,node等)是多线程的,这些宿主环境通过某种方式使得JavaScript拥有了异步的属性。

当我们不需要等待IO设备结果返回时,浏览器的主要线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去,这样就实现了异步操作。

强调:JavaScript是单线程,是指JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序。但实现JavaScript的环境是多线程的,以浏览器为例,浏览器为这些耗时任务开辟了另外的线程,主要包括http请求线程,浏览器定时触发器,浏览器事件触发线程,这些任务是异步的。

结语

此篇比较偏理论,后续会写一些关于JavaScript的事件轮询机制,以及如何用JavaScript实现异步等文章来帮助大家理解JavaScript。

希望能够解决大家工作和学习中的一些疑问,避免不必要的时间浪费,有不严谨的地方,也请大家批评指正,共同进步!
转载请注明出处,谢谢!
交流方式:QQ1670765991

猜你喜欢

转载自blog.csdn.net/zf2014122891/article/details/85539386