从Javascript的设计上而言,是一门单线程非阻塞脚本语言,如何理解?
这个问题可分成两部分来解释:
javascript
运行时只包含 一个消息队列,这里的每个消息都对应一个相关联的函数。这个队列遵循 FIFO(first in first out)机制,总是从最先进入的消息开始处理,处理时:
在进行 IO 或者网络请求时,一般都是通过 事件 和 回调机制 来进行的,例如当发送一个 json
异步数据请求后,就会认为这个函数执行完成了,会继续从消息队列中获取下一个消息来处理。等到网络请求返回后,会向队列中塞入一个新消息,继续等候处理。
但也是有例外的,比如 alert
对话框或者是同步XHR
,如果没有处理完成,消息队列会是一直阻塞的。当然,除非特殊场合,我们要尽量避免这种情况发生。
你只要理解单线程就好了,非阻塞是说它的异步吧,其实还是借由宿主环境底层的多线程或者多进程去实现,怎么实现它不管,你能玩的就那么一个线程,设计上就是这么设计的,但是实现上又有各种玩法,所以强调设计上而言
10 回答11.4k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
8 回答6.4k 阅读
2 回答2.9k 阅读✓ 已解决
3 回答1.5k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
我们都知道,javascript从诞生之日起就是一门单线程的非阻塞的脚本语言。这是由其最初的用途来决定的:与浏览器交互。
单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务。
而非阻塞则是当代码需要进行一项异步任务(无法立刻返回结果,需要花一定时间才能返回的任务,如I/O事件)的时候,主线程会挂起(pending)这个任务,然后在异步任务返回结果的时候再根据一定规则去执行相应的回调。
单线程是必要的,也是javascript这门语言的基石,原因之一在其最初也是最主要的执行环境——浏览器中,我们需要进行各种各样的dom操作。试想一下 如果javascript是多线程的,那么当两个线程同时对dom进行一项操作,例如一个向其添加事件,而另一个删除了这个dom,此时该如何处理呢?因此,为了保证不会 发生类似于这个例子中的情景,javascript选择只用一个主线程来执行代码,这样就保证了程序执行的一致性。
当然,现如今人们也意识到,单线程在保证了执行顺序的同时也限制了javascript的效率,因此开发出了web worker技术。这项技术号称让javascript成为一门多线程语言。
然而,使用web worker技术开的多线程有着诸多限制,例如:所有新线程都受主线程的完全控制,不能独立执行。这意味着这些“线程” 实际上应属于主线程的子线程。另外,这些子线程并没有执行I/O操作的权限,只能为主线程分担一些诸如计算等任务。所以严格来讲这些线程并没有完整的功能,也因此这项技术并非改变了javascript语言的单线程本质。
可以预见,未来的javascript也会一直是一门单线程的语言。