js单线程执行异步任务的原理

各位学前端的小伙伴大家好~

大家都知道JavaScript作为浏览器的脚本语言之一,最大的特性就是单线程,那大家有没有思考过既然JavaScript是单线程,但又同时可进行异步操作,这两者不是完全相反的嘛?今天小张就带你一探究竟~~

JS是单线程,这句话没错。但更确切的说JS只有一个主线程,但是其实他还有一些其他线程的,当然所有函数任务只可以在主线程执行。

JS作为浏览器的脚本语言,于是在设计之处就决定了它必须为单线程,至于为什么必须要设计成单线程不懂的小伙伴可以翻翻本人以前的博客

其实啊,JS作为浏览器的脚本,其最根本的作用就是实现用户与浏览器的交互行为,当一个用户要删除一个A,又同时向A中添加内容的时候,若是多线程,应该怎么样去处理?没有办法处理,若是单线程就很简单了,用户先执行那个操作,我们主线程就进行哪一个,不会出现任何冲突。

那么JS明明单线程,但又同时可进行异步操作,是如何做到的呢?接下来就给咱们讲讲重点!

首先我们要明确一个概念,那就是任务队列,单线程只有上一个任务结束,才能执行下一个任务,所以就会面临一个问题,比如当我们使用Ajax读取网络数据,会消耗大量的时间,但是又不得不等着结果出来,再往下执行。所以JS语言的设计者意识到,这时主线程完全可以不管IO设备(输入输出设备,如Ajax等),挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。

于是呢,任务就被分成两种,一种是同步任务,一种是异步任务

1、同步任务:只有上一个任务执行完成后,才可执行下一个任务,在主线程中

2、异步任务:这个队列的所有任务都是不进入主线程执行,而是被浏览提供的线程执行,当执行完毕后就会产生一个回调函数,并且通知主线程,在主线程执行完当前所执行的任务后,就会调取最早通知自己的回调函数,使其进入主线程中执行,比如ajax请求,再主线程中呈现的就是请求结果。

同异步之间的协同

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在任务队列之中放置一个事件。(回调函数callback)。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。(循环执行这一步)

所谓”回调函数”(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

原来这就是我们常说的单线程与异步是必须要依赖于浏览器的!

以上就是我对JS是单线程为什么可以同时进行异步操作的总结,如其他小伙伴还有什么问题欢迎评论区留言讨论,谢谢~~

你可能感兴趣的:(javascript)