简述JS单线程异步实现原理

对于这个问题我也一直处于半懂不懂状态中,今天读了阮一峰老师的讲解,恍然大悟啊!

附上阮一峰老师的博客~

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

下面是我自己理解了!

一、单线程

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

这样命名很不方便?为什么要这样设计?这事有一定原因的。

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

二、异步

JS明明单线程,但又同时可进行异步操作,这两者不是完全相反的嘛?

没错,JS是单线程,但是JS是在浏览器中运行的脚本语言,它的宿主,浏览器可不是单线程的,这时候,大家又会产生疑问,这两者之间有什么关系呢?下面我们就来讲讲:

1、任务队列

单线程只有前一个任务结束,才能执行下一个任务。

<think>嗯,用户想了解阻塞、非阻塞、同步和异步之间的区别,特别是在编程中的应用场景。首先,我需要回顾一下这些概念的基本定义,确保自己理解正确。根据提供的引用资料,阻塞和非阻塞主要关注程序在等待操作完成时的状态,而同步和异步则关注的是消息通知的机制。 首先,阻塞和非阻塞的区别。阻塞调用会让当前线程挂起,直到操作完成,期间不能执行其他任务。比如,当调用一个阻塞的read函数时,线程会一直等待数据准备好,期间CPU无法处理其他事情。而非阻塞调用会立即返回,无论操作是否完成,线程可以继续执行其他任务,但需要不断轮询来检查状态。这可能会导致CPU资源的浪费,但提高了响应性。 接下来是同步和异步的区别。同步指的是调用方主动等待结果,而异步则是被调用方通过回调或事件通知调用方。例如,同步I/O在数据从内核缓冲区复制到用户空间时,线程仍然阻塞等待,而异步I/O则在整个操作完成后才通知线程,期间线程可以自由处理其他任务。需要注意,同步并不一定意味着阻塞,比如非阻塞的轮询也是同步的一种,因为需要主动检查状态。 然后,应用场景方面。阻塞和同步常用于简单的场景,代码容易编写,但并发能力差。异步非阻塞适合高并发服务器,如Node.js,能处理大量请求而不阻塞线程。例如,引用中提到的高并发服务器使用异步非阻塞I/O来提高吞吐量。 可能用户混淆的地方在于同步与非阻塞的组合,比如非阻塞的同步调用,这时候虽然是非阻塞,但需要主动轮询,属于同步的范畴。而异步则必须有回调机制,无需主动等待。需要明确区分这些组合的情况,避免误解。 另外,引用中的资料提到,同步可能导致CPU资源浪费,因为线程虽然处于激活状态,但无法进行其他操作。而异步I/O在数据复制阶段也不会阻塞,这点与同步I/O不同。比如,信号驱动I/O和异步I/O的区别在于通知的时机,前者通知可以开始I/O,后者通知I/O完成。 用户可能还想知道如何在实际编程中选择合适的模型。比如,对于需要快速响应和高并发的场景,选择异步非阻塞;对于简单的顺序处理,同步阻塞更直接。同时,需要权衡编程复杂度和性能需求。 总结时,应该将这些概念对比列出,明确各自的定义、行为特点和应用场景,帮助用户清晰理解。同时,结合引用中的例子,如高并发服务器的应用,使解释更具体。</think>### 阻塞、非阻塞、同步、异步的区别及编程应用场景 #### 一、**阻塞与非阻塞的区别** 1. **定义与行为特征** - **阻塞**:调用方发出请求后,必须等待操作完成才能继续执行后续代码。在此期间,当前线程会被挂起,无法执行其他任务[^3]。 示例:同步阻塞的 `read()` 函数,线程会一直等待数据从内核缓冲区复制到用户空间。 - **非阻塞**:调用方发出请求后立即返回(无论操作是否完成),线程可以继续执行其他任务,但需要通过轮询等方式主动检查操作结果[^4]。 示例:非阻塞的 `read()` 函数返回 `EAGAIN` 错误时,表示数据未准备好,需稍后重试。 2. **资源消耗对比** - 阻塞模式下线程会闲置等待,可能浪费 CPU 时间片资源[^3]。 - 非阻塞模式需主动轮询,可能增加 CPU 开销(如空循环检查状态)。 3. **应用场景** - **阻塞**:简单顺序逻辑(如单线程脚本)、对实时性要求不高的场景。 - **非阻塞**:高并发 I/O 操作(如网络服务器处理多个连接)[^1]。 --- #### 二、**同步与异步的区别** 1. **定义与通信机制** - **同步**:调用方主动等待结果返回,**关注操作完成的方式**。 示例:调用 `send()` 后需检查返回值确认是否发送成功。 - **异步**:调用方发出请求后继续执行,通过回调函数或事件通知获取结果,**关注消息通知的机制**[^2]。 示例:异步 I/O 操作完成后通过信号通知应用程序。 2. **关键差异** - 同步操作中,数据从内核缓冲区复制到用户缓冲区时,线程可能阻塞(同步阻塞)或非阻塞轮询(同步非阻塞)[^2]。 - 异步操作中,数据复制阶段也不会阻塞线程,由系统完成后再通知应用进程[^4]。 3. **应用场景** - **同步**:需要明确顺序执行的任务(如文件读写后立即处理数据)。 - **异步**:高吞吐量场景(如 Web 服务器处理海量请求)、需要避免线程阻塞的 GUI 程序[^1]。 --- #### 三、**组合模式与编程实践** 1. **常见组合** - **同步阻塞**:代码简单,但效率低(如传统单线程服务器)。 - **同步非阻塞**:通过轮询提高响应性(如 `select/poll` 模型)。 - **异步非阻塞**:高效处理并发(如 Node.js 的 Event Loop)[^1]。 2. **编程模型示例** - **同步阻塞代码片段**(Python): ```python data = socket.recv(1024) # 阻塞直到数据到达 print("Received:", data) ``` - **异步非阻塞代码片段**(JavaScript): ```javascript fs.readFile('file.txt', (err, data) => { if (err) throw err; console.log(data); }); ``` --- #### 四、**总结对比表** | 特性 | 阻塞 | 非阻塞 | 同步 | 异步 | |-----------------|----------------------|----------------------|----------------------|----------------------| | **线程状态** | 挂起等待 | 立即返回,可执行其他任务 | 主动等待结果 | 继续执行,通过回调通知 | | **资源效率** | 可能浪费 CPU | 需轮询,增加 CPU 开销 | 可能阻塞或轮询 | 高效利用 CPU | | **典型应用** | 简单脚本、低并发场景 | 高并发服务器 | 顺序任务处理 | 高吞吐量系统 | ---
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值