如何在现代JavaScript中编写异步任务
Posted 3h8iaa1l
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在现代JavaScript中编写异步任务相关的知识,希望对你有一定的参考价值。
在本文中,我们将探讨过去异步执行的 javascript 的演变,以及它是怎样改变我们编写代码的方式的。我们将从最早的 Web 开发开始,一直到现代异步模式。
作为编程语言, JavaScript 有两个主要特征,这两个特征对于理解我们的代码如何工作非常重要。首先是它的同步特性,这意味着代码将逐行运行,其次是单线程,任何时候都仅执行一个命令。
随着语言的发展,允许异步执行的新工件出现在场景中。开发人员在解决更复杂的算法和数据流时尝试了不同的方法,从而导致新的接口和模式出现。
同步执行和观察者模式
如简介中所述,JavaScript 通常会逐行运行你编写的代码。即使在最初的几年中,该语言也有这种规则的例外,尽管很少,你可能已经知道了它们:HTTP 请求,DOM 事件和time interval。
如果我们通过添加事件侦听器去响应用户对元素的单击,则无论语言解释器在运行什么,它都会停止,然后运行在侦听器回调中编写的代码,之后再返回正常的流程站长交易。
与 interval 或网络请求相同,addEventListener,setTimeout 和 XMLHttpRequest 是 Web 开发人员访问异步执行的第一批工件。
尽管这些是 JavaScript 中同步执行的例外情况,但重要的是你要了解该语言仍然是单线程的。我们可以打破这种同步性,但是解释器仍然每次运行一行代码。
例如检查一个网络请求。
不管发生什么情况,当服务器恢复运行时,分配给 onreadystatechange 的方法都会在取回程序的代码序列之前被调用。
对用户交互做出反应时,也会发生类似的情况。
你可能会注意到,我们正在连接一个外部事件并传递一个回调,告诉代码当事件发生时应该怎么做。十多年前,“什么是回调?”是一个非常受期待的面试问题,因为在很多代码库中到处都有这种模式。
在上述每种情况下,我们都在响应外部事件。不管是达到一定的时间间隔、用户操作还是服务器响应。我们本身无法创建异步任务,我们总是 观察 发生在我们力所能及范围之外的事件。
这就是为什么这种方式的代码被称为观察者模式的原因,在这种情况下,它最好由 addEventListener 接口来表示。很快,暴露这种模式的事件发送器库或框架开始蓬勃发展。
NODE.JS 和事件发送器
Node.js 是一个很好的例子,它的官网把自己描述为“异步事件驱动的 JavaScript 运行时”,所以事件发送器和回调是一等公民。它甚至已经实现了一个 EventEmitter 构造函数。
这不仅是通用的异步执行方法,而且是其生态系统的核心模式和惯例。Node.js 开辟了一个在不同环境中甚至在 web 之外编写 JavaScript 的新时代。当然异步的情况也是可能的,例如创建新目录或写文件。
你可能会注意到,回调函数将第一个参数接作为 error ,如果得到了预期的响应数据,则将其作为第二个参数。这就是所谓的错误优先回调模式,它成为作者和贡献者为包和库所做的约定。
Promise 和没完没了的回调链
随着 Web 开发面临的更复杂的问题,出现了对更好的异步工件的需求。如果我们查看最后一个代码段,则会看到重复的回调链,随着任务数量的增加,回调链的扩展效果不佳。
例如,我们仅添加两个步骤,即文件读取和样式预处理。
我们可以看到,由于多个回调链和重复的错误处理,编写程序变得越来越复杂,代码变得更加难以理解。
Promise、包装和链模式
当 Promises 最初被宣布为 JavaScript 语言的新成员时,并没有引起太多关注,它们并不是一个新概念,因为其他语言在几十年前就已经实现了类似的实现。事实上自从它出现以来,他们就改变了我从事的大多数项目的语义和结构。
Promises不仅为开发人员引入了用于编写异步代码的内置解决方案,,而且还开辟了Web 开发的新阶段,成为 Web 规范后来的新功能(如 fetch)的构建基础。
从回调方法迁移到基于 promise 的方法在项目(例如库和浏览器)中变得越来越普遍,甚至 Node.js 也开始缓慢地迁移到它上面。
以上是关于如何在现代JavaScript中编写异步任务的主要内容,如果未能解决你的问题,请参考以下文章