async 与 await 基础详解

(一)async,await的作用

async , await 一起使用,实际是为了解决异步操作的新方法
但是区别于 promisepromise 是对异步操作进行封装,解决回调地狱的一种解决方案,本质上是为了让程序员书写异步代码更加方便,阅读起来更加简洁,明朗,可以说promise就是异步操作的一个容器

async , await,则是promise的一个容器,他对已经包裹好的异步操作的promise进行二次包装,使异步代码看起来像同步一样执行,比promise更加形象的把代码呈现出来

记得引入一下 axios 的 cdn 或者自己 npm install axios一下

cdn地址:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

传统promise形式

// 简单封装一下axios函数
const getAction = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
function getItems(url) {
  getAction(url)
    .then((value) => {
      console.log(value)
    })
}
getItems(url)

async,await形式

async,await形式的代码看起来会更像同步执行,阅读体验也很不错

// 简单封装一下axios函数
const getAction = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
async function getItems(url) {
  const response = await getAction(url)
  console.log(response)
}
getItems(url)

(二)async,await的基本知识点

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。

// 简单封装一下axios函数
const getAction = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
async function getItems(url) {
  return await getAction(url)
}
getItems(url).then((value) => {
  console.log(value)
})

正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function f() {
  // 等同于
  // return 'hello world';
  return await 'hello world';
}
f().then(v => console.log(v))
// "hello world"

这里面实际上有一个隐式的调用,会隐式调用Promise.resolve()

async function f() {
  // 等同于
  // return 'hello world';
  // return await 'hello world';
  return await Promise.resolve('hello world');
}
f().then(v => console.log(v))

async函数运行后一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句(简单说就是,async的函数虽然是异步的,但是函数里面的执行顺序却是同步的)

比如下面这个例子,定义一个异步函数(定时器),5秒后才会执行下一句 await 语句

// 简单封装一下axios函数
const getAction = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
// 定时器
async function timeout(ms) {
  await new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function getItems(url, ms) {
  console.log(`${ms / 1000}秒后输出response...`)
  await timeout(ms)
  const response = await getAction(url)
  console.log(response)
}
getItems(url, 5000)

(三)async 函数有多种使用形式。

async 不仅可以用在函数声明上,还可以用在函数表达式,箭头函数,对象的方法,Class 的方法上

// 函数声明
async function foo() { }

// 函数表达式
const foo = async function () { };

// 箭头函数
const foo = async () => { };

// 对象的方法
let obj = { 
  async foo() { } 
};
obj.foo().then(()=>{})

根据这些特性,我们还可以把上面添加.then回调的函数,变得更加扁平化一些

// 简单封装一下axios函数
const getAction = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
function getItems(url) {
  return getAction(url)
}
(async () => {
  const items = await getItems(url)
  console.log(items)
})();

(四)async,await 处理多个请求

前文已经说了,async的函数虽然是异步执行,但是函数体里面的内容却是同步的,只有前面的await结束,才会执行下一个await的异步请求
所以当多个请求一起处理时,从上往下写的形式,只有前面一个执行完成才能执行下一个,页面加载速度就会很慢

处理并行的异步请求
下面两种方法是相同的,喜欢哪个用哪个

// 简单封装一下axios函数
const Get = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
async function getItems(url) {
  const [response1, response2] = await Promise.all([Get(url), Get(url)])
  console.log(response1)
  console.log(response2)
}
getItems(url)
// 简单封装一下axios函数
const Get = (url) => axios({ method: 'get', url });
const url = "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
async function getItems(url) {
  const response1Promise = Get(url)
  const response2Promise = Get(url)
  let foo = await response1Promise;
  let bar = await response2Promise;
  console.log(foo)
  console.log(bar)
}
getItems(url)

(五)async,await 的错误处理

如果 await 后面的异步操作出错,那么等同于 async 函数返回的 Promise 对象被 reject

async function f() {
  await new Promise((resolve, reject) => {
    throw new Error('出错了');
  });
}
f()
  .then(v => console.log(v))
  .catch(e => console.log(e))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值