zoukankan      html  css  js  c++  java
  • 【译】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),
      }; 
    }

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

    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可能更容易。

     

  • 相关阅读:
    团队项目总结
    CVPR顶会论文爬取存入MySQL数据库(标题、摘要、作者、PDF链接和原地址)
    如何做好招聘----CEO如何识别优秀的候选人
    《产品方法论 俞军》 读书笔记总结--2021年的第41/100本
    《增长黑客 sean ellis》 读书笔记总结--2021年的第40/100本
    《参与感 黎万强》 读书笔记总结--2021年的第37/100本
    《领导梯队 拉姆查兰》 读书笔记总结--2021年的第35/100本
    《一本书读懂财报》 读书笔记总结--2021年的第34/100本
    《OKR工作法 克里斯蒂娜沃尔克》精读 读书笔记总结----《创业必读书第13本》--创业第三关做好业务:1.如何做好组织管理的第2本
    《美学思维》 混沌大学商学院第12章 读书笔记总结--2020年的第28/100本
  • 原文地址:https://www.cnblogs.com/pjl43/p/10093201.html
Copyright © 2011-2022 走看看