异步函数在JavaScript中是好事。 好的方面是异步函数是非阻塞的,因此是快速的-特别是在Node.js上下文中。 缺点是处理异步函数可能很麻烦,因为有时您必须等待一个函数完成才能获得其“回调”,然后再进行下一个执行。
有几种方法可以发挥异步函数调用的优势并正确处理它们的执行,但是其中一种方法要比其他方法好得多(Spoiler:它是Async / Await)。 在此快速阅读中,您将了解Promises的来龙去脉以及Async / Await的用法,以及我们对两者比较的看法。
享受吧!
承诺与回调????
作为JavaScript或Node.js开发人员,正确理解Promises和Callback之间的区别以及它们如何协同工作至关重要。
两者之间存在细微但重要的差异。 在每个Promise的核心处,都有一个回调来解决某种数据(或错误),这些数据冒泡到被调用的Promise上。
回调处理程序:
调用validatePassword()函数:
下面的代码段显示了从头到尾的验证密码的完整检查(它是静态的,必须与我小时候最喜欢的卡通人物“ bambi”匹配) :
该代码的注释非常好,但是,如果您感到困惑,则仅在从promise调用reject()的情况下才执行catch。 由于密码不匹配,我们调用reject() ,因此“捕获”错误并将其发送到done()函数。
承诺????
与传统的基于回调的方法相比,Promise为执行,编写和管理异步操作提供了一种更简单的选择。 它们还允许您使用类似于同步try / catch的方法来处理异步错误。
承诺还提供了三种独特的状态 :
- 待定 -承诺的结果尚未确定,因为产生结果的异步操作尚未完成。
- 已实现 -异步操作已完成,并且Promise具有价值。
- 已拒绝 -异步操作失败,并且承诺将永远无法实现。 在拒绝状态下,promise会指出操作失败的原因 。
当承诺待定时,它可以转换为已实现或已拒绝状态。 但是,一旦实现或拒绝了承诺,它将永远不会转变为任何其他状态,其价值或失败原因也不会改变。
缺点????
许诺不做的一件事就是解决所谓的“回调地狱”,这实际上只是一系列嵌套函数调用。 当然可以,一个电话就可以。 对于许多调用,您的代码很难甚至很难读取和维护。
循环承诺mis
为了避免使用JavaScript深度嵌套的回调,人们会假设您可以简单地遍历Promises,将结果返回到对象或数组,完成后它将停止。 不幸的是,这并不容易。 由于JavaScript的异步特性,如果您遍历每个Promise,则在代码完成时不会调用“完成”事件。
解决这种情况的正确方法是使用Promise.all() 。 此功能在标记为完成之前等待所有完成(或第一个拒绝)。
错误处理????
使用多个嵌套的Promise调用进行错误处理就像开车蒙住眼睛一样。 祝您好运,找出哪个Promise抛出了错误。 最好的选择是完全删除catch()方法,并选择加入全局错误处理程序(并用手指操作),如下所示:
浏览器:
Node.js:
注意:以上两个选项是确保捕获错误的仅有两种方法。 如果您错过添加catch()方法,它将被代码吞没。
异步/等待? ????
Async / Await允许我们编写看起来是同步的异步JavaScript。 在这篇文章的前面部分,向您介绍了,那些假定简化异步流,避免回调地狱承诺,但他们没有。
回调地狱? ????
回调地狱是用于描述以下情况的术语:
注意:作为示例,这是一个API调用,该调用将从一个数组中获取4个特定用户。
噢,这是丑陋和占用的空间吨的代码。
Async / Await是JavaScript中最新,最重要的东西,它使我们不仅可以避免回调地狱,还可以确保我们的代码干净并且可以正确捕获错误。 我对Async / Await最为着迷的是,它是基于Promises(非阻塞等)构建的,但仍允许代码被读取和读取,就好像它是同步的一样。 这就是力量所在。
注意:这是一组相同的API调用示例,它们在一半以上的代码行中从一个数组中检索4个用户:
看中吧? ????
而且由于Async / Await是基于Promises构建的,因此您甚至可以将Promise.all()与await关键字一起使用:
注意:Async / await由于其同步特性而稍慢一些。 连续多次使用它时应小心,因为await关键字会停止执行其后的所有代码-与在同步代码中完全一样。
如何开始使用异步/等待? ????
使用Async / Await令人惊讶地易于理解和使用。 实际上,它可以在最新版本的Node.js中本地获得,并且正在迅速向浏览器发展。 现在,如果要在客户端使用它,则需要使用Babel ,这是一个易于使用和设置的网络编译器。
异步
让我们从async关键字开始。 可以将其放在函数之前,如下所示:
等待
关键字await使JavaScript等待该承诺完成并返回其结果。 这是一个例子:
完整示例:
为什么异步/等待更好? ????
既然我们已经讨论了Promises和Async / Await必须提供的许多功能,让我们回顾一下为什么我们( Stream )认为Async / Await是我们代码库的最佳选择。
- 异步/等待允许使用更少的代码行,更少的键入和更少的错误来提供简洁简洁的代码库。 最终,它使复杂的嵌套代码再次可读。
- 使用try / catch处理错误(在一个地方,而不是在每个调用中)
- 与您从Promises收到的模棱两可的错误堆栈相比,错误堆栈很有意义,因为堆栈很大且难以定位错误的来源。 最重要的是,错误指向错误源自的函数。
最后的想法????
我可以说Async / Await是过去几年中已添加到JavaScript的最强大的功能之一。
不到一天的时间就了解了语法,并了解了我们的代码库在这方面的混乱情况。 将我们所有基于Promise的代码转换为Async / Await总共花费了大约两天的时间,这实质上是一次完整的重写-只是显示了使用Async / Await时所需的代码很少。
最后,感谢您阅读这篇文章。 如果您对其他帖子感兴趣,请查看Stream博客 。 而且,如果您对Stream的出色表现以及我们的工作感兴趣,请通过此5分钟的教程试用API。
如果您喜欢这篇文章,请给我鼓掌(如果感觉特别好,请给我鼓掌)(如果喜欢,则为50)。 谢谢!
编码愉快! ????
From: https://hackernoon.com/javascript-promises-and-why-async-await-wins-the-battle-4fc9d15d509f