JS中的异步编程

92 阅读7分钟

 前言:

这是本人对于JS中异步编程的理解,欢迎大家的交流,以及如果发现错误欢迎大家的指正,十分感激

1.异步编程是什么

异步编程是一种编程范式,它允许程序在等待某些操作完成(如I/O操作、网络请求等)时,不必阻塞当前执行线程,而是可以继续执行其他任务。这种编程方式可以显著提高应用程序的性能和响应性,尤其是在处理耗时操作时。

在JavaScript中,异步编程尤为重要,因为JavaScript运行在单线程环境中。如果一个操作耗时过长,会阻塞整个线程,导致应用程序无法响应用户输入或其他事件。异步编程允许JavaScript引擎在等待异步操作完成的同时,继续执行其他代码,从而避免了这种阻塞。

异步编程的应用场景非常广泛,包括但不限于:

  • 网络请求和响应处理
  • 文件读写操作
  • 定时器(setTimeout, setInterval)
  • Web Workers
  • 动画和用户界面更新

总而言之,需要延时执行或者等待特定条件出发执行的代码块可以用异步编程的思想实现

举个例子,我们平时上厕所肯定是先方便,再冲水,所以冲水这个条件是等待方便完再触发的,这又何尝不是一种异步编程呢?

2.异步编程从何而来

异步编程的概念并不是由JavaScript首创,它起源于计算机科学和操作系统中对于并发和并行处理的需求。以下是异步编程发展的几个关键点:

  1. 操作系统中的并发: 在早期的操作系统中,为了提高资源利用率和系统吞吐量,引入了多任务处理的概念。操作系统通过时间分片或优先级调度等技术,允许多个任务看似同时运行,这实际上是一种并发执行,每个任务在很短的时间内交替执行。
  2. I/O操作的异步性: 由于I/O操作(如磁盘读写、网络通信)通常比CPU计算要慢得多,为了不浪费CPU资源,操作系统提供了异步I/O操作。这意味着进程可以在发起I/O请求后继续执行,不必等待I/O操作完成。
  3. 多线程和事件驱动模型: 随着多核处理器的普及,多线程编程成为了一种常见的并行处理手段。同时,事件驱动模型(如Node.js采用的模型)允许在单个线程上处理大量并发连接,通过注册回调函数来响应事件,从而实现异步I/O。
  4. 编程语言的支持: 许多现代编程语言都提供了对异步编程的支持,如C#的asyncawait关键字,Python的asyncio库,以及JavaScript的Promise和async/await语法。
  5. JavaScript的异步模型: JavaScript最初设计为一种简单的脚本语言,用于处理表单验证等客户端任务。随着Web应用的复杂性增加,JavaScript开始承担更多的责任,包括处理复杂的用户界面和网络通信。由于JavaScript在浏览器中是单线程的,为了避免长时间的脚本执行阻塞用户界面,引入了异步编程模型,如回调函数、事件循环等。
  6. Node.js的影响: Node.js的推出进一步推广了JavaScript的异步编程模型。Node.js使用事件循环和非阻塞I/O模型来支持高并发的网络应用,这使得JavaScript的异步编程模型被广泛接受和应用。

异步编程的发展是与计算机硬件的进步、操作系统的演进以及编程语言的发展紧密相连的。随着Web技术和移动设备的普及,异步编程已经成为现代软件开发中不可或缺的一部分。

3.异步编程出现是为了解决什么问题

  1. 避免阻塞: 在单线程环境中,长时间运行的任务会阻塞主线程,导致应用程序无法响应用户输入或其他任务。异步编程允许主线程在等待某些操作完成时继续执行其他任务,从而避免阻塞。
  2. 提高性能: 通过异步执行耗时的操作(如I/O、网络请求等),应用程序可以在等待这些操作完成的同时处理其他任务,从而提高整体性能。
  3. 资源利用率: 在多任务环境中,异步编程可以提高CPU和I/O资源的利用率,避免因等待I/O操作完成而造成的资源浪费。
  4. 响应式UI: 对于具有图形用户界面的应用程序,异步编程可以确保UI的响应性,即使在后台执行复杂或耗时的操作时,用户界面也能保持流畅。
  5. 并发处理: 异步编程允许程序以非阻塞的方式处理多个并发任务,这对于服务器端编程尤其重要,因为它可以同时处理来自多个客户端的请求。
  6. 事件驱动架构: 异步编程是事件驱动架构的基础。在这种架构中,程序的执行流程由外部事件(如用户操作、网络消息等)触发,而不是由程序内部的顺序执行控制。
  7. 可扩展性: 异步编程有助于构建可扩展的应用程序。通过异步处理,应用程序可以在单个线程或少量线程上处理大量任务,而无需为每个任务创建新的线程。
  8. 简化编程模型: 尽管异步编程在概念上可能比同步编程更复杂,但它可以简化某些类型的程序设计,特别是那些涉及大量I/O操作的程序。
  9. 适应现代硬件: 随着多核和多处理器硬件的普及,异步编程可以帮助程序更有效地利用现代硬件的并行处理能力。
  10. 网络应用的复杂性: 随着Web应用变得越来越复杂,需要处理大量的并发连接和实时数据流,异步编程成为处理这种复杂性的关键技术。

总的来说,异步编程是为了解决在单线程或多线程环境中,如何高效、有效地处理耗时操作和并发任务的问题,同时保持应用程序的响应性和性能。

4.异步编程如何实现

1

有两种实现方法,第一种为 async ,await 方法,async 关键字应该放在包含 await 表达式的函数上,

await 放在要等待的代码块前面,这种方法比较简洁,个人比较推荐

​编辑

2

promise方法:

Promise 是 JavaScript 中用于异步编程的一种对象。它代表了一个可能现在还没有结果,但预期将来会有结果的值。Promise 的状态可以是三种之一:

  1. Pending(进行中) :初始状态,既不是成功,也不是失败状态。
  2. Fulfilled(已成功) :意味着操作成功完成。
  3. Rejected(已失败) :意味着操作失败。
  4. Promise 通过构造函数 new Promise 创建,它接受一个执行器函数(executor function)作为参数,该函数有两个参数,通常命名为 resolvereject
  5. resolve 在异步操作成功时调用,并且返回操作的结果。
  6. reject 在异步操作失败时调用,并且返回操作的错误。
  7. .then 方法用于指定当 Promise 解决(fulfilled)时应该执行的回调函数。它也可以接受一个可选的第二个回调函数,用于处理 Promise 被拒绝(rejected)的情况。
  8. .catch 方法用于处理 Promise 被拒绝的情况。它接受一个回调函数作为参数,该回调函数接收 Promise 被拒绝时的原因作为参数。
  9. .finally 方法用于指定无论 Promise 是解决还是被拒绝,都会执行的回调函数。这个回调函数不接收任何参数,并且它返回的值(如果有的话)会被忽略。

.then()是爱人,Ta可能看不上你

.catch()是备胎,.then()不要你的时候他帮你兜底

.finally()是家人,不管怎么样他都会一直在(执行)

​编辑