zoukankan      html  css  js  c++  java
  • async函数

    async函数

    async函数是什么?

    他就是Generator函数的语法糖

    async函数就是将grnerator函数的(*) 替换成async ,将 yield替换成 await

     

    改进

    (1)内置执行器

    Generator 函数执行必须依靠执行器, 而async函数自带执行器. 也就是说 async函数的执行与普通函数一模一样, 只要一行

    //async 函数自动执行
    const asyncReadFile = async function(){
       await console.log('hello')
       await console.log('world')
    }
    //如果使用Generator函数需要next方法才能真正执行
    //生成器对象
    function* get(){
       yield console.log('hello')
       yield console.log('world')
    }
    let g = get()

    g.next() // 'hello'
    g.next() // 'world'

    // 升级
    async function get(){
       await setTimeout(()=>{
      console.log('hello')
      },2000) // 两秒后执行 输出hello
       await console.log('world')
    }

     

    (2)改进之处

    async和await , 比起星号和yield , 语义就更加清楚 , async表示函数里有异步操作, await表示紧跟在后面的表达式需要等待结果

    async function get(){
       await new Promise((resolve,reject)=>{
           setTimeout(()=>{
               console.log('hello')
               resolve('李大庆')
          })
      })
       await console.log('world')
    }

     

    (3)更广的是适用性

    async函数的await命令后面, 可以是Promise 对象和原始类型的值 (数值、字符串和布尔值, 但这是会自动转成立即resolved 的 Promise 对象 )

     

    (4)返回值是Promise

    async 函数的返回值是 Promise 对象,这比Generator 函数的返回值是 Iterator 对象航标多了 . 你可以用 then 方法指定下一步的操作

     

    axync 函数的语法应用

    axync函数的语法简单, 难点是错误处理机制

    1.async 函数的返回值

    async函数返回以恶 Promise 对象

    async 函数内部 return 语句返回的值, 会成为 then 方法回调函数的参数

    async function f(){
       return 'hello woeld';
    }
    f().then(v => console.log(v))
    //上面代码函数f内部1return 命令返回的值, 会被then 方法回调函数接收到

    //async函数内部跑哦出错误, 会导致返回的Promise 对象变为reject状态. 抛出的错误对象会被catch方法回调函数接收到

    3.await命令

    async function f(){
       await Promise.reject('出错了')
    }
    f()
      .then(v => console.log(v))
    .catch(e =. console.log(e))
    // await 命令后面的Promise对象如果变为reject状态, 则reject的参数会被catch方法的回调函数接收到

    async function f(){
       await Promise.reject('出错了')
       await Promise.resolve('hello world')//不会执行
    }
    // 上面代码中, 第二个await语句是不会执行的, 因为第一个await语句状态变成了reject

    (1) 有时我们希望即使前一个异步操作失败, 也不要中高端后面的异步操作做. 这是可以加功第一个await放在 try...catch 结构里面, 则按不管这个异步是否成功, 第二个都会执行

    (2) 另一种方法是await 后面的Promise 对象再跟一个catch方法, 处理前面可能出现的错误.

    4. 使用注意点

    (1) await 命令后面的Promise对象, 运行结果可能是rejected, 所以最好把await命令放置在try ... catch代码块中

    async function myFunction(){
    try{
    await something()
    }catch(err){
    console.log(err)
    }
    }
    //另一种写法 最好这么写
    async function myFunction(){
       await something().catch(function (err){
           console.og(err)
      })
    }

    (2) 多个await命令后面的异步操作, 如果不存在继发关系, 最好让他们同时触发

    let foo = await getFoo()
    let bar = await getBar()
    //getFoo和getbar 是两个独立的异步操作(即互不依赖) ,被下腭侧给计划关系 这样比较耗时, 因为之哟个体Foo完成以后, 才会执行getbar, 完全而已让他们同时触发
    //写法一 
    let [foo,
        bar] = await Promise
                          .all([
                               getFoo(),
                               getBar()
                          ])
    //写法二
    let footPromise = getFoo()
    let barPromise = getBar()
    let foo = await fooPromise
    let bar = await barPromise

    //上面两中写法, getFoo和getBar的都是同时触发, 这样就会缩短程序的执行时间

     

    async 函数的实现原理

    //async 函数的实现原理,就是将Generator 函数和自执行器, 包装在一个函数里
    async function fn(args){
       // ...
    }
    //等同于
    function fn(args){
       return spawn(function* (){
           // ...
      })
    }
    //所有的async函数都可以直接写成上面的第二种形式, 其中spawn函数就是自执行器

    //原理
    function spawn(genF){
       return new Promise(function (resolve,reject){
           const gen = genF()
           function step(nextF){
               let next
               try{
                   next = nextF()
              }catch(e){
                   return reject(e)
              }
               if(next.done){
                   return resolve(next.value)
              }
               Promise.resolve(next.value).then(function(v){
                   step(function(){ return gen.next(v) })
              }, function(e){
                   step(function(){ return gen.throw(e) })
              })
          }
           step(function(){ return gen.next(undefind) })
      })
    }

    其他问题

     

    未来web前端架构师
  • 相关阅读:
    现代编程语言:Rust (铁锈,一文掌握钢铁是怎样生锈的)
    mRNA(阅读链接)
    技术的极限(13): 对过程和细节的可视化
    现代编程语言:TypeScript
    现代编程语言:JavaScript
    现代编程语言:zig
    现代编程语言:Python(蛇形遍历一颗树)
    炼金术(9): 简约而不简单,永不停歇的测试 -- always_run
    软件性能测试分析与调优实践之路-Web中间件的性能分析与调优总结
    退役记
  • 原文地址:https://www.cnblogs.com/swalT-link/p/13696520.html
Copyright © 2011-2022 走看看