对于这个问题我也一直处于半懂不懂状态中,今天读了阮一峰老师的讲解,恍然大悟啊!
附上阮一峰老师的博客~
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
下面是我自己理解了!
一、单线程
JS是单线程,这句话没错。但更确切的说JS只有一个主线程,但是其实他还有一些其他线程的,当然所有函数任务只可以在主线程执行。
这样命名很不方便?为什么要这样设计?这事有一定原因的。
JS作为浏览器的脚本于是,其最根本的作用就是实现用户与浏览器的交互行为,当一个用户要删除一个A,又同时向A中添加内容的时候,若是多线程,应该怎么样去处理?没有办法处理,若是单线程就很简单了,用户先执行那个操作,我们主线程就进行哪一个,不会出现任何冲突!
二、异步
JS明明单线程,但又同时可进行异步操作,这两者不是完全相反的嘛?
没错,JS是单线程,但是JS是在浏览器中运行的脚本语言,它的宿主,浏览器可不是单线程的,这时候,大家又会产生疑问,这两者之间有什么关系呢?下面我们就来讲讲:
1、任务队列
单线程只有前一个任务结束,才能执行下一个任务。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。
JS语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。
于是呢,任务就被分成两种,一种是同步任务,一种是异步任务
同步任务:只有前一个任务执行完成后,才可执行下一个任务,在主线程中
异步任务:这个队列的所有任务都是不进入主线程执行,而是被浏览提供的线程执行,当执行完毕后就会产生一个回调函数,并且通知主线程,在主线程执行完当前所执行的任务后,就会调取最早通知自己的回调函数,使其进入主线程中执行,比如ajax请求,再主线程中呈现的就是请求结果~
说到了这里,是不是已经清晰了一点了呢?下面就附上这么一张图片~
这这张图片简直太经典了,以至于我无法不去引用他作为我讲解的基础(转引自Philip Roberts的演讲《Help, I’m stuck in an event-loop》)
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件(回调函数callback)。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
“任务队列”是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在”任务队列”中添加一个事件,表示相关的异步任务可以进入”执行栈”了。主线程读取”任务队列”,就是读取里面有哪些事件。
“任务队列”中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入”任务队列”,等待主线程读取。
所谓”回调函数”(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
“任务队列”是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,”任务队列”上第一位的事件就自动进入主线程。但是,由于存在后文提到的”定时器”功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。
这下就很清楚了!原来这就是我们常说的单线程与异步~必须要依赖于浏览器的!
---------------------
作者:鱼活在水中
来源:CSDN
原文:https://blog.csdn.net/qq_39480597/article/details/79662913
版权声明:本文为博主原创文章,转载请附上博文链接!
相关推荐
Node.js采用 事件驱动 和 异步I/O 的方式,实现了一个单线程、高并发的运行时环境,而单线程就意味着同一时间只能做一件事,那么Node.js如何利用单线程来实现高并发和异步I/O?本文将围绕这个问题来探讨Node.js的单...
JavaScript 是单线程语言,意味着任何时刻只能执行一个任务。为了处理异步操作,JavaScript 采用了事件循环机制,通过消息队列管理异步任务的执行顺序。 ### 什么是 event-loop? Event Loop 是 JavaScript 引擎...
CommonJS主要关注同步模块定义,适合在Node.js等单线程环境中使用,因为它假设所有模块都是同步加载的。 相反,Asynchronous Module Definition(AMD)是在CommonJS未能就异步加载JavaScript模块达成共识后分离出来...
178、如何现实servlet的单线程模式 42 179、页面间对象传递的方法 42 180、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 42 181、四种会话跟踪技术 42 182、Request对象的主要方法 43 183、我们在web...
10. **异步编程**:JavaScript具有非阻塞的单线程模型,主要通过回调函数、Promise和async/await处理异步操作,以避免回调地狱并提高代码可读性。 以上只是《JavaScript 权威指南第四版(四)》中部分关键知识点的...
2. **单线程与工作进程**: 虽然Node.js主线程是单线程的,但它通过工作进程(Worker Threads)来实现多线程,以处理计算密集型任务,避免主线程被阻塞。 3. **V8引擎**: Node.js使用Google的V8引擎,使得JavaScript...
python入门到高级全栈工程师培训视频学习资料;本资料仅用于学习,请查看后24小时之内删除。 【课程内容】 第1章 01 计算机发展史 ...15 再插两道JavaScript面试题 16 Model操作之select_related以及...
7. **异步编程**:JavaScript是单线程的,但通过回调、Promise和async/await等机制处理异步操作。`main.js`可能涉及网络请求、定时任务等异步操作。 `README.txt`文件通常是项目中的说明文档,它可能包含以下内容:...
从上世纪80年代简单的单核单线程计算模型,到如今多核处理器及高度网络化的环境,程序员们正处在从传统的命令式编程向新的编程范式的过渡阶段。这种转变不仅要求程序员能够处理异步操作,还必须在保持程序高效运行的...
5. **异步编程**:JavaScript是单线程的,但通过异步处理(如回调函数、Promise、async/await)可以处理非阻塞I/O操作。这在处理网络请求、定时任务等场景中尤为重要。 `README.txt`文件通常包含了项目的基本信息、...
4. **异步编程**:JavaScript是单线程语言,因此理解异步编程至关重要,包括回调函数、Promise、async/await等。 5. **AJAX与Fetch API**:学习如何使用这些API进行异步数据请求,与服务器进行通信,实现页面无刷新...
46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...
6. **异步编程**:JavaScript是单线程的,使用回调函数、Promise和async/await处理异步操作,避免阻塞主线程。 7. **模块系统**:ES6引入了模块系统,通过import和export关键字实现模块间的导入导出。 8. **DOM...
46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例...
46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...
46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 32 47、sleep() 和 wait() 有什么区别? 33 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...
25. **请简述一下Ajax的原理及实现步骤** - Ajax(Asynchronous JavaScript and XML)是一种无需重新加载整个网页即可与服务器交换数据并更新部分网页的技术。 - 实现步骤: 1. 创建XMLHttpRequest对象。 2. 发送...