JavaScript 异步编程和回调

JavaScript 默认是同步的,并且是单线程的。 这意味着代码无法创建新线程并并行运行。 了解异步代码的含义及其外观。

目录

编程语言中的异步性

计算机在设计上是异步的。

异步意味着事情可以独立于主程序流发生。

在当前的消费者计算机中,每个程序都运行一个特定的时间段,然后停止执行以让另一个程序继续执行。 这东西在一个循环中运行得如此之快,以至于无法注意到。 我们认为我们的计算机同时运行许多程序,但这是一种错觉(多处理器机器除外)。

程序在内部使用中断,这是一种发送到处理器以引起系统注意的信号。

我们现在不深入了解它的内部结构,但请记住,程序异步并停止执行是很正常的,直到它们需要注意,允许计算机同时执行其他事情。 当一个程序正在等待来自网络的响应时,在请求完成之前它不能停止处理器。

通常,编程语言是同步的,有些语言提供了一种方法来管理语言中的异步性或通过库。 C、Java、C#、PHP、Go、Ruby、Swift 和 Python 默认都是同步的。 其中一些通过使用线程处理异步操作,产生一个新进程。

JavaScript

JavaScript 默认是 同步的 并且是单线程的。 这意味着代码无法创建新线程并并行运行。

一行行代码依次执行,一行一行,例如:

但 JavaScript 是在浏览器中诞生的,它的主要工作,一开始是响应用户的操作,比如 onClickonMouseOveronChangeonSubmit 等等。 它如何使用同步编程模型做到这一点?

答案在于它的环境。 浏览器 通过提供一组可以处理此类功能的 API 提供了一种方法。

最近,Node.js 引入了非阻塞 I/O 环境,将这一概念扩展到文件访问、网络调用等。

回调

你无法知道用户何时会单击按钮。 所以,你 为点击事件定义一个事件处理程序。 此事件处理程序接受一个函数,该函数将在事件触发时调用:

这就是所谓的 回调

回调是一个简单的函数,它作为值传递给另一个函数,并且只会在事件发生时执行。 我们可以这样做是因为 JavaScript 具有一流的函数,可以将其分配给变量并传递给其他函数(称为 高阶函数

通常将所有客户端代码封装在 window 对象上的 load 事件监听器中,它仅在页面准备就绪时运行回调函数:

回调无处不在,而不仅仅是在 DOM 事件中。

一个常见的例子是使用定时器:

XHR 请求也接受回调,在这个例子中,通过将一个函数分配给一个属性,该属性将在特定事件发生时调用(在这种情况下,请求的状态发生变化):

处理回调中的错误

你如何处理回调错误? 一种非常常见的策略是使用 Node.js 采用的策略: 任何回调函数中的第一个参数都是错误对象: 错误优先回调

如果没有错误,对象就是 null。 如果有错误,它包含错误的一些描述和其他信息。

回调的问题

回调非常适合简单的情况!

然而,每个回调都会增加一层嵌套,当你有很多回调时,代码很快就会变得复杂起来:

这只是一个简单的 4 层代码,但我已经看到了更多层级的嵌套,这并不好玩。

我们如何解决这个问题?

回调的替代方案

从 ES6 开始,JavaScript 引入了几个特性来帮助我们处理不涉及使用回调的异步代码: Promises (ES6) 和 Async/Await (ES2017)。

Node.js 中文网 - 粤ICP备13048890号