async/await是语法糖,是解决js中异步问题的最终解决方案。从字面意思来讲,async是异步,await是等待
- async 用于声明一个函数为异步,返回的就是一个promise对象,可以使用then方法添加回调函数,async函数内部return语句返回的值,会成为then方法回调函数的参数。
- async和await是搭配使用的,如果函数内使用了await但是函数前面并没有async声明,那就会报错。如果一个函数用了async声明,但是内部并没有使用await,那么这个函数跟普通函数也没什么区别,并不具备实际的promise意义。
// 1. 一个普通函数使用 async 进行修饰,那它的返回值就会被包装到一个 Promise 对象中
async function doSomethingAsync() {
// 异步逻辑
return 123
}
// 得到的是一个Promise,Promise中包含了 async 函数的正真的返回值
const result = doSomethingAsync()
console.log(result)
result.then(data => {
console.log(data)
})
// 2. 对一个箭头函数使用 async 关键字
const myAsyncTask = async () => {
return 456
}
const result2 = myAsyncTask()
console.log(result2)
- await 用于等待一个异步方法执行完成。await 操作符只能在异步函数 async function 内部使用。如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果,也就是说它会阻塞后面的代码,等待 Promise 对象结果。如果等待的不是 Promise 对象,则返回该值本身。
- await 后面的就是promise对象,会阻塞代码执行,直到promise出结果之后才会继续往下执行。
async function task1() {
// return 123
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 2000)
})
return p
}
async function start() {
// 对 Promise 对象使用 await,可以得到 Promise 对象中 resolve 出来的数据
const value = await task1()
console.log(value)
}
start()
使用try{} catch(err){}语法进行捕获错误
- 我们在使用promise的时候,就是新建的一个new Promise() 对象,使用这个对象进行.then()成功操作,.catch()失败操作。但是使用async和await的语法时,道理上是在await后面进行阻塞,成功了之后才会继续往下执行,但是如果异步任务执行失败了,也会报错,但是并没有提供对应的语法执行报错功能。
- 所以针对async 和 await 的方式的promise,我们可以使用try{}catch(err){}语法进行捕获错误。我们把可能会发生错误的代码段放进try里面,如果没有错误的话,那就该怎么执行怎么执行,一旦发生错误,就会进入到catch里面,执行catch的代码,接收一个参数err为报错内容,你可以选择把报错打印出来。
- try{}catch(err){} 语法的功能有时候也不是就捕获那种真实的报错,而是假如有些问题我们知道必然会发生,或者就是代码运行过程中必然会出现的错误,无可避免的或者是合理的,我们使用这个语法进行美化。这个语法在很多语言里都有,具有同样的功能,比如说C#,也是同样的思想,那里面是用来捕获异常,并且写的多了,甚至习惯性的在代码外面套上一个try-catch。
如果存在多个await后面的异步操作,如果互相之间没有继发关系(互不依赖),建议使用上面的Promise.all()语法,让它们同时触发。
async 和 await 的优点
async/await的优势在于处理由多个Promise组成的 then 链,在之前的Promise文章中提过用then处理回调地狱的问题,async/await相当于对promise的进一步优化。 假设一个业务,分多个步骤,且每个步骤都是异步的,而且依赖上个步骤的执行结果。