zoukankan      html  css  js  c++  java
  • ES7中的async 和 await

    async 和 await

    一个函数如果加上 async ,那么该函数就会返回一个 Promise

    async function test() {
      return "1"
    }
    console.log(test()) 
    // -> Promise {<resolved>: "1"}
    

    async 就是将函数返回值使用 Promise.resolve() 包裹了下,和 then 中处理返回值一样,并且 await 只能配套 async 使用。

    async function test() {
      let value = await sleep()
    }
    

    async 和 await 可以说是异步终极解决方案了,相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码,毕竟写一大堆 then 也很恶心,并且也能优雅地解决回调地狱问题。

    当然也存在一些缺点,因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低。

    async function test() {
      // 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
      // 如果有依赖性的话,其实就是解决回调地狱的例子了
      await fetch(url)
      await fetch(url1)
      await fetch(url2)
    }
    

    看一个使用 await 的例子:

    let a = 0
    let b = async () => {
      a = a + await 10
      console.log('2', a)
    }
    b()
    a++
    console.log('1', a)
    
    //先输出  ‘1’, 1
    //在输出  ‘2’, 10
    
    • 首先函数 b 先执行,在执行到 await 10 之前变量 a 还是 0,因为 await 内部实现了 generator ,generator 会保留堆栈中东西,所以这时候 a = 0 被保存了下来
    • 因为 await 是异步操作,后来的表达式不返回 Promise 的话,就会包装成 Promise.reslove(返回值),然后会去执行函数外的同步代码
    • 同步代码 a++ 与打印 a 执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10

    上述解释中提到了 await 内部实现了 generator,其实 await 就是 generator 加上 Promise 的语法糖,且内部实现了自动执行 generator

    代码分析题

    function wait() {
      return new Promise(resolve =>
      	setTimeout(resolve,  1000)
      )
    }
    
    async function main() {
      console.time();
      const x = wait();
      const y = wait();
      const z = wait();
      await x;
      await y;
      await z;
      console.timeEnd();
    }
    main();
    

    答案: 输出耗时: 1秒多一点点。
    原因: 3个wait函数在赋值的时候就已经开始执行了。

    稍微改造一下就可以得到3 * 1000 ms以上的结果

    function wait () {
      return new Promise(
        resolve => setTimeout(resolve,  1000)
      )
    }
    
    async function main () {
      console.time()
      const x = await wait()
      const y = await wait()
      const z = await wait()
      console.timeEnd()
    }
    
    main()
    
    今天你学习了吗!!!
  • 相关阅读:
    枚举类
    泛型数组列表
    方法参数
    给一个数字和列表,判断列表中是否存在两个元素之和等于这个数字,并好之两个数的坐标
    selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable报错
    python-selenium提供的execute_script调用js操作
    xlrd读取excel数据封装
    0531-练习题 os.system
    0528 文件操作习题
    05/17
  • 原文地址:https://www.cnblogs.com/nayek/p/11728872.html
Copyright © 2011-2022 走看看