async/await

理解async函数就要先理解generator (生成器)函数,因为async是generator函数的语法糖。

Generator函数

Generator 函数是 ES6 提供的一种异步编程解决方案,可以先理解为一个状态机,封装了多个内部状态,执行Generator函数返回一个遍历器对象,通过遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
语法上,Generator 函数是一个普通函数,但是有两个特征。

  • function关键字与函数名之间有一个*
  • 函数内部使用yield表达式,定义不同的内部状态。
function* myGenerator() {
 	yield 'Hello'
    yield 'world'
    return 'ending'
}
let MG = myGenerator()
console.log(MG.next());
console.log(MG.next());
console.log(MG.next());
console.log(MG.next());

运行结果:
async/await_第1张图片
1)yield 表达式,可以在生成器函数内部暂停代码的执行,使其挂起,此时生成器函数仍然是运行并且是活跃的,其内部资源都会保留下来,只不过是处在暂停状态。
2)next(),在迭代器上调用next()方法,可以使代码从暂停的位置开始继续往下执行。

async/await

 const fs = require('fs')
 const readFile = function(fileName){
      return new Promise(function(resolve,reject){
            fs.readFile(fileName,function(error,data){
            if(error) return reject(error)
                resolve(data)
            })
     })
 }
//generator函数实现
 const gen=function* (){
      const f1 = yield readFile('/etc/fstab');
      const f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
  }
//async实现
const gen1 = async function(){
   const f1 = await readFile('/etc/fstab');
   const f2 = await readFile('/etc/shells');
   console.log(f1.toString());
   console.log(f2.toString()) ;
}

由此可见,async和generator在语法上是类似的。

async做一件什么事情?

带async关键字的函数,它使得你的函数的返回值必定是promise对象
1)如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装
2)如果async关键字函数显式地返回promise,那就以你返回的promise为准

async function fun1(){
  return 'hello'
}
function fun2(){
    return 'async'
}
console.log(fun1());
console.log(fun2());

async/await_第2张图片

await在等什么?

await等的是右侧「表达式」的结果右侧是指await下边的语句(代码)

async function async1(){
   console.log('async1 start');
    await async2()
    console.log('async1 end');
}
async function async2(){
    console.log('async2');
}
console.log('script start');
async1()

async/await_第3张图片

await等到之后,做了一件什么事情?

右侧表达式的结果,就是await要等的东西。
等到之后,对于await来说,分为2种情况
1)不是promise对象
2)是promise对象
如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。

async function async1() {
    console.log("async1 start");
       await async2();
       console.log("async1 end");
   }

   async function async2() {
       console.log("async2");
   }

   console.log("script start");

   setTimeout(function() {
       console.log("setTimeout");
   }, 0);

   async1();

   new Promise(function(resolve) {
       console.log("promise1");
       resolve();
   }).then(function() {
       console.log("promise2");
   });

   console.log("script end");

async/await_第4张图片

async和promise的区别

1)Async/Await 代码看起来简洁一些,使得异步代码看起来像同步代码
2)async await与Promise一样,是非阻塞的。
3)async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数。
调试:
promise

  • promise不能在返回表达式的箭头函数中设置断点
  • 如果你在.then代码块中设置断点,使用Step Over快捷键,调试器不会跳到下一个.then,因为它只会跳过异步代码

async

  • async/await能够使得代码调试更简单
  • 使用await/async时,你不再需要那么多箭头函数,这样你就可以像调试同步代码一样跳过await语句
  • 如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
  • 如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
    promise异步:
ajax('aaa',()=>{
   ajax('bbb',()=>{
        ajax('ccc',()=>{

        })
    })
})
ajax('aaa').then(res=>{
    return ajax('bbb')
}).then(res=>{
    return ajax('ccc')
})

async异步:

 async function fetch(){
     await ajax('aaa')
      await ajax('bbb')
      await ajax('ccc')
  }

你可能感兴趣的:(个人总结,javascript,前端,typescript)