【译】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的重要特性之一,也是目前社区里公认的优秀异步解 ... 
随机推荐
- Linux- RPM与yum软件包安装
			Linux安装及管理程序一.Linux应用程序基础1)应用程序与系统命令的关系2)典型应用程序的目录结构3)常见的软件包封装类型二.RPM包管理工具① RPM软件包管理器Red-Hat Package ... 
- Serverless与Web后端天生不合?
			Serverless/Faas/BaaS 等概念在这几年的技术圈中是绝对的热点词汇之一,国内外众多云厂商也纷纷推出自家的 Serverless 和函数计算产品,微信也依托腾讯云推出了基于 Server ... 
- shell 正则表达式一
			正则表达式用于处理文本,精通运用正则表达式可以有效的解决工作的效率 正则表达式有基础正则表达式和扩展正则表达式区别 grep支持基础的正则表达式,grep -E (egrep)支持扩展正则表达式 1. ... 
- C语言:float类型%d输出
			float类型%d输出 float a=7.5f; 如果用printf("%d",a);输出的是0. 但float型用%d输出是否一定是0呢,答案肯定不都是0: 为什么 7.5 用 ... 
- js检测客户端是否安装
			前言 需求背景:一个web下载页面,需要检测pc是否安装了客户端软件(windows软件).网页上有一个打开客户端按钮.若安装了客户端软件,则直接打开,否则下载软件.支持web下载页面在iframe下 ... 
- Pelles C编译时出现的“POLINK: fatal error: 拒绝访问”问题的一种可能成因
			在使用PellesC编译程序时,第一遍能正常编译执行,第二遍就无法编译,出现以下问题提示: Building NEWprogram2.exe. POLINK: fatal error: 拒绝访问. * ... 
- 一文说清OpenCL框架
			背景 Read the fucking official documents! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: 对不 ... 
- (opencv08)cv.resize()调整图像大小
			(opencv08)cv.resize()调整图像大小 img = cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=N ... 
- 抽奖动画 - lao虎机抽奖
			本文介绍一个lao虎机抽奖动画的实现,lao虎机抽奖在各类商家营销活动中非常常见,这里主要介绍动画的实现过程,其他细节不做详细分析. ps:lao虎机是敏感词,博客园不允许出现,所有老用拼音. 1. ... 
- appium的安装和环境配置教程
			模拟器安装 夜神模拟器下载地址:https://www.yeshen.com/ 无脑安装 jdk环境 安装jdk 安装教程:https://www.cnblogs.com/yhoil/p/148086 ... 
