首页 > 语言 > JavaScript > 正文

深入理解ES7的async/await的用法

2024-05-06 15:26:57
字体:
来源:转载
供稿:网友

在最开始学习ES6的Promise时,曾写过一篇博文 《promise和co搭配生成器函数方式解决js代码异步流程的比较》 ,文章中对比了使用Promise和co模块搭配生成器函数解决js异步的异同。

在文章末尾,提到了ES7的async和await,只是当时只是简单的提了一下,并未做深入探讨。

在前两个月发布的Nodejs V7中,已添加了对async和await的支持,今天就来对这个东东做一下深入的探究。以更加优雅的方法写异步代码。

async/await是什么

async/await可以说是co模块和生成器函数的语法糖。用更加清晰的语义解决js异步代码。

熟悉co模块的同学应该都知道,co模块是TJ大神写的一个使用生成器函数来解决异步流程的模块,可以看做是生成器函数的执行器。而async/await则是对co模块的升级,内置生成器函数的执行器,不再依赖co模块。同时,async返回的是Promise。

从上面来看,不管是co模块还是async/await,都是将Promise作为最基础的单元,对Promise不很了解的同学可以先深入了解一下Promise。

对比Promise,co,async/await

下面我们使用一个简单的例子,来对比一下三种方式的异同,以及取舍。

我们采用mongodb的nodejs驱动,查询mongodb数据库作为例子,原因是mongodb的js驱动已经默认实现了返回Promise,而不用我们单独去包装Promise了。

使用Promise链

MongoClient.connect(url + db_name).then(db=> { return db.collection('blogs');}).then(coll=> { return coll.find().toArray();}).then(blogs=> { console.log(blogs.length);}).catch(err=> { console.log(err);})

Promise的then()方法可以返回另一个Promise,也可以返回一个同步的值,如果返回的是一个同步值,将会被包装成一个Promise。

上面的例子中,db.collection()将返回一个同步的值,即集合对象,但是被包装成Promise,将会透传到下一个then()方法。

上面一个例子,是使用的Promise链。

先连接数据库MongoClient.connect()返回一个Promise,然后在then()方法里获得数据库对象db,然后再获取到coll对象再返回。在下一个then()方法获得coll对象,然后进行查询,查询结果返回,逐层调用then()方法,形成一个Promise链。

在这个Promise链上,如果任何一个环节出现异常,都会被最后的catch()捕捉到。

可以说,这个使用Promise链写的代码,比层层调用回调函数更优雅,流程也更明确。先获得数据库对象,再获得集合对象,最后查询数据。

但是这里有个不怎么“优雅”的问题,在于,每一个then()方法获取的对象,都是上一个then()方法返回的数据。而不能跨层访问。

什么意思,就是说在第三个then(blogs => {})中我们只能获取到查询的结果blogs,而不能使用上面的db对象和coll对象。这个时候,如果要打印出blogs列表后,要关闭数据库db.close()怎么办?

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选