async 和 await(详解)

一、async 和 await

  • promise 使用 .then 链式调用,但也是基于回调函数
  • async/await 更加优雅的异步编程的写法
    1.它是消灭异步回调的终极武器
    2.它是同步语法,也就是用同步的写法写异步的代码

案例1:promise异步加载图片

  • 分别使用 .then 和 await 来获取结果
  • 区别
    1.await 完全没有回调函数
    2.await 是同步写法,异步操作
    3.await 后面不仅仅可以接 promise对象,还可以接 async 函数
//里面函数为AJAX,因此是异步任务
let loadImg = (url)=>{
  const p = new Promise((resolve,reject)=>{
    let newImg = document.createElement("img")
	newImg.src = url
	newImg.onload = function(){
	  resolve(newImg)
	}
	newImg.error = function(){
	  reject(new Error('Could not load Image at url'))
	}
  })
  return p
}

//通过 .then 来获取结果
loadImg(url1)
    .then((img)=>{
	  console.log(img.width,img.height)
	  document.body.appendChild(img)
	  return loadImg(url2)
	})
	.then((img)=>{
	  console.log(img.width,img.height)
	  document.body.appendChild(img)
	})
	.catch((err)=>{
	  console.log(err)
	})
	
//使用 async 和 await 的方法来写,立即执行函数
(async function(){
	// loadImg(url1) 返回 promise 对象
	// await 可以拿到从 resolve 传递过来的 dom 对象
	const img1 = await loadImg(url1)  
	document.body.appendChild(img1)
	
	const img2 = await loadImg(url2)  
	document.body.appendChild(img2)
})()

//await 接 async 函数
async function loadImg1(){
  const img1 = await loadImg(url1)
  return img1
}
(async function(){
	//img1可以拿到 resolve 里面的值
	const img1 = await img1 
	document.body.appendChild(img1)
})()

二、async/await 和 promise的关系

  • async/await 是消灭异步回调的终极武器
  • 但和Promise并不排斥,两者相辅相成
  • 执行 async 函数,返回的是 Promsie 对象
  • await 相当于 Promise 的 then ,then指的是成功,不指失败
  • try…catch 可捕获异常,代替了 Promise的 catch

1.async

async function fn(){
  return 100
}
console.log(fn())  //返回一个成功态的promise对象,result 是 100
fn().then(
  data=>{
    console.log(data)
  }
) // 100

2.await

  • await 后面接 Promise
    1.await p1相当于是 p1.then,并且只是成功态的then
    2.await 和 then 的区别就是:then还需要传回调进去,但 await 可以直接得到值
(async function(){
  const p1 = Promise.resolve(300) //一个成功态的promise对象,且传了result为300
  const res = await p1 // return 值
  console.log(res) // 300
})
  • await 和 .then 的区别
fn().then(
  data=>{
    console.log(data)
  }
)

//await直接通过返回值来接收daita, return data
const res = await fn()  
  • await 接数值
    1.await后面跟的不是promise对象而是数值时,会自动包装成成功态的promise对象
    2.并且传值给 resolve 为400
(async function(){
  const res = await 400 //Promise.resolve(400)
  console.log(res) //400
})()
  • await 接 async 函数
(async function(){
  const res = await fn() //fn()会返回promise对象,原理一样
  console.log(res) //400
})()
  • await 接promise 为空
    1.什么都打印不出来
    2.因为 new Promise 里面没有任何状态改变,而await一直在等待状态改变
    3.只有状态改变了,await才会允许执行后面的代码
(async function(){
  const p = new Promise(()=>{})
  const res = await p
  console.log(res)
  console.log("success")
})()
  • await 接 promise 为 error
    1.会出现报错
    2.await相当于成功态的 .then ,都没有成功,因此不会执行后面的代码
    3.因为JS是单线程的
    4.解决:使用 try…catch 偷偷解决掉 error,保证代码运行
    ——捕获到错误就不会影响后面的输出
(async function(){
  const p = Promise.reject("error")
  const res = await p
  console.log(res)
  console.log("success")
})()    //什么都打印不出来
(async function(){
  const p = Promise.reject("error")
  try{
    const res = await p
    console.log(res)
  }catch(error){
    console.log(error)
  }
  console.log("success")
})()    //打印出 error 和 success

三、执行顺序

  • 代码中存在 await,则需要等待该行执行完才执行下面的代码
function timeout(){
  return new Promise(resolve=>{
    setTimeout(()=>{
	  console.log(1)
	  resolve()//成功态
	})
  })
}

//情况一
async function fn(){
  timeout()
  console.log(2)
}
fn() //打印出 2 一秒后 1

//情况2
async function fn(){
  await timeout()
  console.log(2)
}
fn() //1秒后打印出 1 2
//写法二
function timeout(){
  return new Promise(resolve=>{
    setTimeout(()=>{
	  resolve(1)//成功态,传递参数1
	})
  })
}
async function fn(){
  const res = await timeout() //需要一个变量来接收await return的参数
  console.log(res)
  console.log(2)
}
fn() //1秒后打印出 1 2

四、async 和 await 的实质

  • Promise一般用来解决层层嵌套的回调函数
  • async/await 是消灭异步回调的终极武器
  • JS还是单线程,还是得有异步,还是得基于 event loop(轮询机制)
  • async/await 只是一个语法糖

案例2 :请求多份数据,但后一份数据的请求必须依赖上一份数据的请求结果

  • 解决:
    1.可以使用promise的.then 链式层层调用
    2.也可以使用 async/await ,用同步的代码来解决异步问题
    ——依次获取数据,完全是同步的写法
    ——await会等待该行代码完全运行,才执行后面的代码
async function getDate(){
  const res1 = await request("./a.json")
  console.log(res1)
  
  const res1 = await request("./b.json")
  console.log(res2)
  
  const res1 = await request("./c.json")
  console.log(res3)
}
  • 51
    点赞
  • 372
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
async/await 是一种异步编程模型,它是基于 Promise 的语法糖。async/await 让异步代码看起来更像同步代码,使得代码更加易读、易写,并且能够避免回调地狱。 async/await 的核心是 async 函数。async 函数在定义时使用 async 关键字进行修饰,它返回一个 Promise 对象。在 async 函数中,可以使用 await 关键字来等待一个 Promise 对象的结果返回,await 关键字只能在 async 函数中使用。 当我们使用 await 关键字等待一个 Promise 对象时,如果 Promise 对象的状态是已完成(fulfilled),那么 await 表达式的结果就是 Promise 对象的 resolved 值;如果 Promise 对象的状态是已拒绝(rejected),那么 await 表达式会抛出一个错误,我们可以使用 try-catch 语句来处理这个错误。 下面是一个使用 async/await 的示例代码: ``` async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } } ``` 在这个示例中,fetchData 函数是一个 async 函数,它使用 await 关键字等待一个 Promise 对象的结果。在 try 块中,我们使用 await 关键字等待 fetch 函数返回的 Promise 对象,以获取响应对象。然后,我们再次使用 await 关键字等待 response.json() 方法返回的 Promise 对象,以获取响应数据。最后,我们将响应数据输出到控制台中。如果任何一个 Promise 对象被拒绝,catch 块会捕获这个错误,并输出到控制台中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值