async/await

从字面意思来理解。async 是异步的意思,而 await 是 等待 ,所以理解 async用于申明一个function是异步的,而 await 用于等待一个异步方法执行完成。

async

async声明function是一个异步函数,返回一个promise对象,可以使用 then 方法添加回调函数。async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function test() {
  return 'test';
}
console.log(test); // [AsyncFunction: test] async函数是[`AsyncFunction`]构造函数的实例
console.log(test()); // Promise { 'test' }

// async返回的是一个promise对象
test().then(res=>{
  console.log(res); // test
})

// 如果async函数没有返回值 async函数返回一个undefined的promise对象
async function fn() {
  console.log('没有返回');
}
console.log(fn()); // Promise { undefined }

// 可以看到async函数返回值和Promise.resolve()一样,将返回值包装成promise对象,如果没有返回值就返回undefined的promise对象

await

await 操作符只能在异步函数 async function 内部使用。如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成返回其处理结果,也就是说它会阻塞后面的代码,等待 Promise 对象结果。如果等待的不是 Promise 对象,则返回该值本身

async function test() {
    return new Promise((resolve)=>{
      setTimeout(() => {
          console.log('2秒后test');
          resolve('test 1000');
      }, 2000);
    })
  }
  function fn() {
      console.log('fn');
    return 'fn';
  }
  
  async function next() {
      let res0 = await fn(),
          res1 = await test(),
          res2 = await fn(),
          res3 = await test();
          console.log('被阻塞')
          console.log(await Promise.all([res1,res2])) 

  }
  console.log('1')
  next(); // 
  setTimeout(() => {
    console.log('settime');
    
}, 3000);
  console.log('1')

输出:
1//先执行script整体代码  输出1 fn 1
fn
1//宏任务settimeout 
2秒后test
fn
settime//3秒后输出settime
2秒后test//4秒后输出
被阻塞
['test 1000','fn']//6秒后输出

async/await优点

async/await的优势在于处理由多个Promise组成的 then 链,async/await相当于对promise的进一步优化。 假设一个业务,分多个步骤,且每个步骤都是异步的,而且依赖上个步骤的执行结果。

// -------------promise------------
function submit() {
  console.log('submit');
  // 经过俩个校验 多级关联 promise传值嵌套较深
  check1().then(res1=>{
    check2(res1).then(res2=>{
       /*
        * 提交请求
        */
    })
  })
}
// -------------async/await-----------
async function asyncAwaitSubmit() {
    let res1 = await check1(),
        res2 = await check2(res1);
        console.log(res1, res2);
        /*
        * 提交请求
        */
}


项目实践开发中的使用总结

await后面的代码相当于用.then包裹住,await要接上一个promise对象并且只能在async函数中使用await可以获取到promise对象的一个解构

若使用try catch语句,try中的代码块看为一个整体的宏任务

如果使用了try catch和await语句, catch中会捕获到await中的promise的reject状态和抛出的错误,会执行catch中的语句,相当于.catch,注意await后面的代码不会执行,因为后面的代码为await成功的回调

注意看以下3个例子

    const onSubmit = async () => {
      try {//可以看成2部分代码块,await后面的给.then的成功回调包裹
        const res = await Promise.resolve(222)//后面的代码相当于给包裹进一个.then(()=>{},)中第一个回调参数中
        console.log('@@@@@@@@@@',res)
      } catch(err) {
        console.log(err,'11111')
        
      }
    }
// @@@@@@@@@@  222


   const onSubmit = async () => {
      try {//可以将这代码块看成一整块
        const res =  Promise.reject(222)
        console.log('@@@@@@@@@@',res)
      } catch(err) {//error不为222
        console.log(err,'11111')
        
      }
    }

//@@@@@@@@@@ Promise {<rejected>: 222}  //没有await解构,故输出promise对象,后面的console不受影响,没被包裹进.then的回调里
 11111
 Uncaught (in promise) 222


    const onSubmit = async () => {
      try {
        const res = await Promise.reject(222)
        console.log('@@@@@@@@@@',res)
      } catch(err) {//相当于.catch的写法
        console.log(err,'11111')
        
      }
    }

//222 '11111'       注意console @@@@@@没被执行,因为这是成功的回调函数

阅读剩余
THE END