JavaScript 是单线程的而且是异步的机制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 是单线程的而且是异步的机制相关的知识,希望对你有一定的参考价值。

浏览器中的js程序是单线程的,那异步调用是怎么实现的呢?计时器是靠谁实现的呢?单线程难道是一边执行程序一边计时吗?

好了 …………之前就有好多的疑问  ,现在按我的理解和大家说一说

一、javascript单线程

  在浏览器中,执行JS程序只有一个线程,所以是单线程,所以执行顺序就是从上到下依次执行,同一段时间内只能有一段代码被执行。你可能会问,为什么不用多线程呢,这样不是更能充分利用CPU吗?

  ps:只能说早期的页面非常简单,所以我认为设计者没有考虑多线程的问题 (本人猜想的哈,勿喷!!)。另外,JavaScript主要用来处理用户与界面的交互,以及操作DOM;可以设想一下,如果一个线程要求删除DOM,另一个线程要求修改呢,浏览器听谁的??这就增加了程序设计的复杂度,所以简单点好啊,你说是不是。

  ps:虽然JavaScript是单线程的,可是浏览器内部不是单线程的啊,你的一些I/O操作、定时器和事件监听是由浏览器提供的其他线程完成的……

  ##如果想利用多线程处理一些耗时较长的任务,可以使用html5提供的Web Worker、

二、任务队列和事件循环

  理解异步机制的两个要点:任务队列和事件循环

  ps:技术分享

三、异步机制

有了上面两节做铺垫,理解异步机制就容易多了。拿ajax来说,当页面的单线程执行xhr.send()之后,对于页面来说发送任务已经完成了。怎么发送,那是浏览器的事,和单线程无关;什么时候响应,这事说不准。为了及时地得到响应的内容,在单线程中注册相应的事件就好xhr.onreadystatechange = fn() {...}。注册之后,浏览器会在内部的其他线程中自动地帮我们监听该事件。直到该事件被触发,浏览器会在任务队列中添加一个任务等待该单线程执行。

四、定时器

setTimeout的作用是在间隔一定的时间后,将回调函数插入任务队列中,等栈中的同步任务都执行完毕后,再执行。因为栈中的同步任务也会耗时,所以间隔的时间一般会大于等于指定的时间。

setTimeout(fn, 0)的意思是,将回调函数fn立刻插入任务队列,等待执行,而不是立即执行。看一个例子:

技术分享

五、总结

所谓的单线程并不孤单,它的背后有浏览器的其他线程为其服务,其异步也得靠其他线程来监听事件的响应,并将回调函数推入到任务队列等待执行。单线程所做的就是执行栈中的同步任务,执行完毕后,再从任务队列中取出一个事件(没有事件的话,就等待事件),然后开始执行栈中相关的同步任务,不断的这样循环。

 

以上是关于JavaScript 是单线程的而且是异步的机制的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript单线程和异步机制

Javascript异步机制

js运行机制

javascript事件环(EventLoop)

十分钟理解JavaScript引擎的执行机制

对JavaScript中异步同步机制以及线程深入底层了解