async和await

288 阅读4分钟

async和await

  • asyncawait两种语法结合可以让异步代码像同步代码一样

  • asyncawait关键字让我们可以用一种更简洁的方式写出基于promise的异步行为,而无需刻意的链式调用

  • async用来声明异步函数,函数会返回一个promise对象

  • await用来暂停异步函数代码的执行,等待promise解决

async

  • async是一个加在函数前面的修饰符

  • async修饰的函数会默认返回一个promise对象,可以使用then方法添加回调函数

  • 返回的promise对象的结果是由async函数执行的返回值的结果来决定的

1、当async函数内部返回的是一个非promise对象时,则该返回的值会成为then方法中的回调函数的参数

async function fnOne() {
  return 521
}
fnOne().then(res => {
  console.log(res)
})
console.log(fnOne());

在这里插入图片描述

2、 当async函数内部抛出错误时,会将返回的promise对象的状态改变为reject。而抛出的错误不仅可以使用then方法的第二个回调函数接收到也可以被catch方法中的回调函数所接收到

async function fn() {
  throw new Error("出错了")
}

fn().then(
  res => console.log(res),
  rej => console.log(rej)
)
// 或者
// fn().catch(
//   v => console.log(v)
// )
console.log(fn());

在这里插入图片描述

3、当async函数内部返回的是一个promise对象并且该promise的结果为成功,则成功的值也会成为then方法中第一个回调函数中的参数

async function fn() {
  return new Promise((resolve, reject) => {
    resolve("成功")
  })
}

fn().then(
  res => console.log(res),
  rej => console.log(rej)
)
console.log(fn());

在这里插入图片描述

4、当async函数内部返回的是一个promise对象并且该promise的结果为失败,则失败的值会成为then方法中第二个回调函数中的参数,也会成为catch方法中回调函数的参数

async function fn() {
  return new Promise((resolve, reject) => {
    reject("失败")
  })
}

fn().then(
  res => console.log(res),
  rej => console.log(rej)
)
// 或者
// fn().catch(
//   v => console.log(v)
// )
console.log(fn());

在这里插入图片描述

await表达式

await 表达式

  • await必须写在async函数中,但是async函数中可以没有await

  • await的右侧表达式一般为promise对象,也可以是其他的值,它会返回该对象的结果

  • 如果await右侧的表达式为其他的值,则直接将该值作为await的返回值

async function fn() {

  return await 521
  // 等同于
  // return 521
}

fn().then(
  res => console.log(res),
  rej => console.log(rej)
)

console.log(fn());

在这里插入图片描述

  • 如果await右侧的表达式为promise对象并且该promise对象的结果是成功的,那么await会返回该promise对象成功的值,可以使用then方法来接收到该结果值
async function fn() {
  return await new Promise((resolve, reject) => {
    resolve("成功")
  })
}

fn().then(
  res => console.log(res),
  rej => console.log(rej)
)

console.log(fn());

在这里插入图片描述

  • 如果await右侧的表达式为promise对象并且该promise对象的结果是失败的,那么await会返回该promise对象失败的值,可以使用then方法,catch方法以及try...catch来捕获错误
async function fn() {
  // 使用trycatch方法
  try {
    return await new Promise((resolve, reject) => {
      reject("失败")
    })
  } catch (error) {
    console.log(error);
  }
}

// 或者then方法
// fn().then(
//   res => console.log(res),
//   rej => console.log(rej)
// )
// 或者catch方法
// fn().catch(
//   rej => console.log(rej)
// )

console.log(fn());

使用then方法和catch方法 在这里插入图片描述 使用try...catch方法: 在这里插入图片描述

  • async函数内部有多个await语句时,任何一个await语句后面promise对象变为reject状态,那么整个async函数就会中断,即后续的await函数将不会执行

例:

async function fn() {
  await Promise.reject("失败")
  await Promise.resolve("成功")   //不会执行
}

fn().then(
  res => console.log(res)
).catch(
  err => console.log(err)
)

console.log(fn());

在这里插入图片描述

当需要前一个await函数操作失败,也不要中断后续的await函数时,可以使用try...catch,将失败的await函数放入其中,这样不管前者的await函数操作是否成功,后续的await函数都将不会受到影响

async function fn() {
  try {
    await Promise.reject("失败")
  } catch (error) {
    console.log(error);
  }
  return await Promise.resolve("成功")
}

fn().then(
  res => console.log(res)
).catch(
  err => console.log(err)
)

console.log(fn());

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

async function fn() {

  await Promise.reject("失败").catch(
    err => console.log(err)
  )
  return await Promise.resolve("成功")
}

fn().then(
  res => console.log(res)
).catch(
  err => console.log(err)
)

console.log(fn());

在这里插入图片描述

async与await结合发送Ajax

// 使用Promise来定义一个发送Ajax的方法
function setAjax(url) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.send();
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve(xhr.response);
        } else {
          reject(xhr.status);
        }
      }
    }
  })
}

// 平常方式使用then方法和catch方法
// setAjax('https://api.apiopen.top/getJoke').then(data => {
//   console.log(data)
// }).catch(err => {
//   console.log(err)
// })


// 使用async和await方法
async function sendmsg() {
  return await setAjax('https://api.apiopen.top/getJoke')
}

sendmsg().then(
  data => console.log(data)
).catch(
  err => console.log(err)
)

成功: 在这里插入图片描述 失败: 在这里插入图片描述