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

其他问题

 

posted @ 2020-09-19 15:48  swalT_link  阅读(222)  评论(0编辑  收藏  举报