async和await
-
async
和await
两种语法结合可以让异步代码像同步代码一样 -
async
和await
关键字让我们可以用一种更简洁的方式写出基于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)
)
成功:
失败: