开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情
前言
昨天学习ES6标准中的Promise新特性,提供了一种更优雅的方式来编写异步编程代码,但在某些情况下还是不够优雅,因此在ES7标准中提供了async/await关键字来进一步优化异步编码方式,下面就来了解一下。
Promise存在的问题
通常我们都需要通过AJAX发送请求给服务器,当存在多个请求并且依赖于上一个ajax的请求结果时,根据Promise的写法我们很容易就会写出如下代码:
function ajaxRequest (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: 'GET',
success: function (res) {
resolve(res);
},
error: function(err) {
reject('请求失败');
}
})
})
};
ajaxRequest('justUrl').then((d) => {
console.log(d);
return ajaxRequest(d.url);
}).then((d) => {
console.log(d);
return ajaxRequest(d.url);
}).then((d) => {
// TODO
console.log(d);
}).catch((err)=>{
console.log( err );
})
在逻辑简单时,如上代码并没有啥问题。但如果请求逻辑复杂,传递参数为对象等,就同样会出现以前的回调地狱。因此在ES7中就提供了async/await这两个关键字。
async/await
async关键字用于声明一个函数是否为异步函数,而await则用于异步函数中的同步等待(只能用于被aysnc关键字声明的函数中)。
async function testAsync() {
const response = await new Promise(resolve => {
setTimeout(() => {
resolve("等待");
}, 1000);
});
console.log(response); // 等待
}
testSync();// testAsync方法本身还是异步
我们通常使用async/await和promise来配合使用,用于实现串行并行等处理实现。
async function testAjaxRequest() {
let response1 = await ajaxRequest("url1");
let response2 = await ajaxRequest(response1.url);
let response3 = await ajaxRequest(response2.url);
}
例如我们通过await就可以很优雅的实现串行请求了,或者实现并行请求
async function asyncAwaitFunction(str) {
return await new Promise((resolve) => {
setTimeout(() => {
resolve(str)
}, 1000);
})
}
async function parallel() {
const func1 = asyncAwaitFunction('func1') //并行执行
const func2 = asyncAwaitFunction('func2') //并行执行
}
parallel()
错误处理
当我们使用Promise发送网络请求等操作时,肯定会出现错误情况,当调用reject方法时,我们可以使用try-catch语句进行包裹处理。
async function catchErr() {
try {
await new Promise( (resolve, reject) => {
setTimeout( () => {
reject( "网络请求出错" ); // 或者throw "error"
}, 1000 );
})
}
catch ( err ) {
console.log("错误情况",err );
}
}
catchErr(); //http error...
小细节
- await关键字后面应该跟着一个Promise的对象,如果是其他类型的返回值也可以,不过await就没有效果了。
- await只能在异步函数中使用