专业的编程技术博客社区

网站首页 > 博客文章 正文

举例说明Javascript中的async/await和Promise

baijin 2024-10-11 10:46:33 博客文章 16 ℃ 0 评论

引言

最开始我们使用JavaScript的时候就有回调的概念,它并没有什么特别的地方,由于JavaScript的异步性质,许许多多地方都需要用到回调,并不能立即获取我们想要的结果,如下使用Node.js读取文件:

当我们想要进行多个异步操作就会出现问题。想象以下这样的一些场景(所有的操作都是异步的)

  • 我们再查询出用户的信息后,需要根据用户的信息到某个服务器去请求用户的图片
  • 查出图片后,我们需要将图片转换格式,比如从PNG转换成JPEG
  • 如果转换成功,我们发送成功的邮件通知
  • 发送之后我们在记录下这个时间点的日志

那么代码看起来可能像下面这样:

这样的代码让我不禁想起来了无数的if阶梯嵌套,一不小心就陷入回调地狱,这样的缺点很明显:

  • 代码变得更难阅读
  • 错误处理起来相对复杂,就更容易导致代码的错误

Promise

为了避免回调地狱,Javascript众神创造了promise,我们就可以链式编程了,而不是内嵌套回调,那么改一下代码如下:

虽然以上代码已经是一种从上到下的流程,但仍然存在一些问题

  • 需要.then
  • 需要.catch处理异常,而不是try/catch的方式
  • 多个promise

异步功能

在ES2017(ES8)中引入了异步功能,这让我们更简单的来使用promise,异步编程的好处最直观的就是:

  • 使用async/await避免链式的promise
  • 它们是异步的执行,不过给了你同步编程的感觉

因此,在我们理解async/await之前,你需要对promise有一定的了解

语法

注意async放的位置,特别是箭头函数,异步的声明也可以用在对象方法和类方法上

  • 备注:构造函数不能用

与普通函数的区别就是异步函数返回的是一个promise对象,如下

它和下面的等效,这里我们是手动创建一个promise,而不是使用async

换句话说,异步函数的返回值总是包含在Promise.resolve中

异步函数await

先看一段代码,在分析:

  • fn执行时,评估 const a = await 9,实际上内部转换成了const a await Promise.resolve(9);
  • 我们使用了await,fn暂停到a获取值
  • delayAndGetRandom(1000)导致fn暂停一秒后获取到随机值

错误处理

通过以上示例大致的知道,如何使用async和await了,但是我们并没有看到异常处理的部分,所以接下来就看一下

canRejectOrReturn()是一个异步函数,它的最终结果为 'perfect number'或拒绝 Error('Sorry, number too big'),我们来写一下捕获这段异常的代码

对比另一个示例

少了await关键字,catch永远都不会执行,这是常见的错误或陷阱,就是没有使用await

并行化

有些时候我们可能需要并行的执行一些操作,那么我们继续要使用Promise.All了,示例如下:

Promise.all接收一个promises数组作为输入并返回一个promise作为输出

总结

异步功能在开发中变得越来越重要了,也将被越来越多的开发人员所采用,所以对我们来说,了解异步就显得非常重要了,希望这边文章能够帮助大家了解JS中的异步编程,如果可以,请麻烦点个关注吧,谢谢!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表