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),
};
}

此代码看起来逻辑正确。但这是错误的。

  1. await bookModel.fetchAll()将等到fetchAll()返回。
  2. 然后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可能更容易。

最新文章

  1. lucene5学习 - 索引基本操作(创建,查询,更新,删除,分页)
  2. vs2008下面wince错误MSDiscoCodeGenerator
  3. Saas
  4. 解决MVC4发布在IIS7后,路径无法访问.apk文件的解决方法
  5. IE8 HACK介绍
  6. hiho #1310 : 岛屿 (dfs,hash)
  7. 如何通过Socket TCP发送并接收一个文件?
  8. 升级xcode6和ios8后,unity遇到的一些小问题
  9. 跟开涛老师学shiro -- shiro简介
  10. iTunes Connect TERMS OF SERVICE
  11. curl 解析
  12. UVa 129 困难的串
  13. spring quartz开发中使用demo
  14. OpenCV4Android
  15. JAVA 解析、编辑nginx.conf
  16. 微信公众号H5支付遇到的那些坑
  17. 【转载】 spring事物配置,声明式事务管理和基于@Transactional注解的使用
  18. Spring IOC分析
  19. css3整理--transform
  20. Netty Reator(三)Reactor 模型

热门文章

  1. Python单元测试框架unittest之断言(assert)
  2. Python - 字符串常用函数详解
  3. 「CF585E」 Present for Vitalik the Philatelist
  4. [刘阳Java]_BeanNameViewResolver视图解析器_第8讲
  5. vite插件-自动生成vue组件文档
  6. C++11 左值引用和右值引用与引用折叠和完美转发
  7. spring-4-申明事务
  8. 微信小程序云开发-列表下拉刷新
  9. 创建Rdemo项目
  10. Maven作用及应用