【译】JavaScript async / await:好的部分,陷阱和如何使用
async/await提供了一种使用同步样式代码异步访问资源的选项,而不会阻塞主线程。然而,使用它有点棘手。在本文中,我们将从不同的角度探讨async / await,并将展示如何正确有效地使用它们。
async / await的好处
async/await给我们带来的最重要的好处是同步编程风格。我们来看一个例子吧。
// async / await
async getBooksByAuthorWithAwait(authorId){
const books = await bookModel.fetchAll();
return books.filter(b => b.authorId === authorId);
}
// promise
getBooksByAuthorWithPromise(authorId){
return bookModel.fetchAll()。then(
books => books.filter(b => b.authorId === authorId));
}
很明显,async/await版本比承诺版本更容易理解。
另一个不太明显的好处是async关键字。它声明getBooksByAuthorWithAwait()函数返回值保证是一个promise,以便调用者可以调用getBooksByAuthorWithAwait().then(...)或await getBooksByAuthorWithAwait()安全。想想这个例子(不好的做法!):
getBooksByAuthorWithPromise(authorId){
if(!authorId){
return null;
}
return bookModel.fetchAll()。then(
books => books.filter(b => b.authorId === authorId));
}
在上面的代码中,getBooksByAuthorWithPromise可以返回一个promise(正常情况)或一个null值(例外情况),在这种情况下,调用者不能.then()安全地调用 。而通过async声明,就可以安全的用.then()调用了。
Async/await可能会产生误导
有些文章将async / await与Promise进行比较,并声称它是JavaScript异步编程演变的下一代,我不同意。Async / await是一种改进,但它只不过是一种语法糖,它不会完全改变我们的编程风格。
从本质上讲,异步函数仍然是承诺。在正确使用异步函数之前,您必须了解promises,更糟糕的是,大多数情况下您需要使用promises和异步函数。
考虑上面示例中的getBooksByAuthorWithAwait()和getBooksByAuthorWithPromises()函数。请注意,它们不仅在功能上相同,而且具有完全相同的界面!
getBooksByAuthorWithAwait()如果直接调用,这意味着将返回一个承诺。
嗯,这不一定是坏事。只有这个名字await让人感觉“哦,这可以将异步函数转换为同步函数”,这实际上是错误的。
Async/await陷阱
那么使用async/await时会出现什么错误?这是一些常见的。
太顺序了
虽然await可以使您的代码看起来像同步,但请记住它们仍然是异步的,必须注意避免过于顺序。
async getBooksAndAuthor(authorId){
const books = await bookModel.fetchAll();
const author = await authorModel.fetch(authorId);
return {
author,
books:books.filter(book => book.authorId === authorId),
};
}
此代码看起来逻辑正确。但这是错误的。
await bookModel.fetchAll()将等到fetchAll()返回。- 然后
await authorModel.fetch(authorId)将被执行。
请注意,authorModel.fetch(authorId)它不依赖于bookModel.fetchAll()的结果,实际上它们可以并行调用!但是,在这里使用了await,这两个调用变为顺序,并且总执行时间将比并行版本长得多。
这是正确的方法:
async getBooksAndAuthor(authorId){
const bookPromise = bookModel.fetchAll();
const authorPromise = authorModel.fetch(authorId);
const book = await bookPromise;
const author = await authorPromise;
return {
author,
books:books.filter(book => book.authorId === authorId),
};
}
或者更糟糕的是,如果你想逐个获取一个项目列表,你必须依赖Promise:
async getAuthors(authorIds){
// 错误,这将导致顺序调用
// const authors = _.map(
// authorIds,
// id => await authorModel.fetch(id));
// 正确
const promises = _.map(authorIds,id => authorModel.fetch(id));
const authors = await Promise.all(promises);
}
简而言之,您仍然需要异步考虑工作流,然后尝试await同步编写代码。在复杂的工作流程中,直接使用promises可能更容易。
【译】JavaScript async / await:好的部分,陷阱和如何使用的更多相关文章
- JavaScript async/await:优点、陷阱及如何使用
翻译练习 原博客地址:JavaScript async/await: The Good Part, Pitfalls and How to Use ES7中引进的async/await是对JavaSc ...
- JavaScript async/await 基础知识
async 作用: async函数返回一个 Promise对象,无论内部有没有await关键字. await 作用: await等待的是一个表达式,这个表达式的计算结果是 Promise 对象 或者是 ...
- 【译】Async/Await(一)——多任务
原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...
- 【译】Async/Await(二)——Futures
原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...
- 【译】Async/Await(三)——Aysnc/Await模式
原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...
- 【译】Async/Await(四)—— Pinning
原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...
- 【译】Async/Await(五)—— Executors and Wakers
原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...
- JavaScript - async/await 基础示例
一个函数如果被 async 修饰,无论内部是否有 await的异步操作,都会返回一个 Promise 对象 demo 1 async function basicAsync() { let resul ...
- 七 vue学习 async/await
1: javaScript async/await: 调用async函数的时候,是异步的,函数后面的代码继续执行.! async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解 ...
随机推荐
- XXE学习(待更新)
XXE基础 XXE(XMl External Injection),即XML外部实体注入漏洞. XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体得加载,导致可以加载恶意外部文件,造成文件读取 ...
- 「CF555E」 Case of Computer Network
「CF555E」 Case of Computer Network 传送门 又是给边定向的题目(马上想到欧拉回路) 然而这个题没有对度数的限制,你想歪了. 然后又开始想一个类似于匈牙利的算法:我先跑, ...
- HTTP 2.0标准针对HTTP 1.X的五点改进
HTTP 2.0兼容HTTP 1.X,同时大大提升了Web性能,进一步减少了网络延迟,减少了前端方面的工作.HTTP 1.X存在的缺点如下: 1)HTTP 1.0一次只允许在一个TCP连接上发起一个请 ...
- 微信小程序云开发-云存储-上传单个视频到云存储并显示到页面上
一.wxml文件 <!-- 上传视频到云存储 --> <button bindtap="chooseVideo" type="primary" ...
- 微信小程序云开发-云存储-使用云开发控制台存储文件
一.存储 进入[云开发控制台]>点击[存储].将需要存储的文件通过[上传文件]方式上传上去.或者通过拖拽的方式上传文件. 二.存储文件的类型 可以存储的文件有很多,常见的文件类型包括:word ...
- SQlL 中 where 1=1
提升某种执行效率? 其实,1=1 是永恒成立的,意思无条件的,也就是说在SQL语句中有没有这个1=1都可以. 这个1=1常用于应用程序根据用户选择项的不同拼凑where条件时用的. 如:web界面查询 ...
- 构建后端第3篇之---springb @Alias注解使用
write by 张艳涛 in 202210210,after today i will write aritles by english,because english is so diffent ...
- 【动画消消乐 】HTML+CSS 吃豆豆动画 073
前言 Hello!小伙伴! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 自我介绍 ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计 ...
- windows环境30分钟从0开始快速搭建第一个docker项目(带数据库交互)
前言 小白直接上手 docker 构建我们的第一个项目,简单粗暴,后续各种概念边写边了解,各种概念性的内容就不展开,没了解过的点击 Docker 教程 进行初步了解. Docker 是一个开源的应用 ...
- 单片机学习(二)开发板LED灯的控制
目录 开发板上LED灯相关的电路图 点灯 LED闪烁 LED流水灯 其他效果 灯光二进制计数器 进阶版流水灯 开发板上LED灯相关的电路图 这是P2相关7个引脚的电路图,在默认情况下它是直接接着VCC ...