async表达式,也是他们常说的async/await,是在ES8中导入的新优点,主要就目地是为的是精简采用如前所述Promise的API时所需的句法。async和awaitURL让采用 Promises显得难,而无须故意地拉艾初始化Promise。因此与冗余的.then较之,标识符时效性更快。上面就来如是说呵呵它的具体内容采用和准则。
一、async表达式
1. 用语
在表达式新闻稿的后面加之asyncURL,就变为的是 async 表达式。
async function f() {
return hello world;
}
2. 回到值
async 表达式的回到值是两个 Promise 示例,Promise 示例的结论由 async 表达式的回到值下定决心:
假如回到的是两个 Promise 示例,最后获得的 Promise 第一类的状况与值与回到的 Promise 示例完全一致。
假如回到的是两个非 Promise 示例的值,async 表达式回到的两个状况为 resolved 的 Promise 示例,value 是表达式内回到的值。
假如没回到值,async 表达式回到两个状况为resolved 的 Promise 示例,value 是undefined。
假如放出严重错误,async 表达式回到两个状况为 rejected 的 Promise 示例,reason 是放出的严重错误。
二、await表达式
async function main(){
let result = await Promise.resolve(hello world);
console.log(result); // hello world
};
main();
async function f(){
let result = await 998;
console.log(result); // 998
}
f();
async function foo(){
let result = await {
then(resolve, reject){
setTimeout(() => {
resolve(success)
}, 2000);
}
};
console.log(result); // success
}
foo();
1. 准则
await 表达式必须写在 async 表达式的里面。但async表达式中可以没 await,不过一般二者是一起采用的。
await 表达式可以取到 Promise 示例的结论(是状况发生改变后传到回调表达式的值)。当然,必须等到 Promise 示例的状况发生变化,await 表达式才能取到值。
2. 关于 await 的右侧的表达式
一般为 Promise 实例,await 表达式的值是该 Promise 示例的结论。
假如是个其他类型的值(非 Promise 类型),await 表达式的值是这个值。
后面是两个 thenable 第一类(即定义then方法的第一类),那么会将其等同于 Promise 第一类。(如是说 Promise.resolve() 方法的时候如是说过 thenable 第一类)。
3. 注意
假如 await 右侧是个状况为失败的 Promise 示例,会放出异常。他们建议将 await 表达式放在try…catch结构里面。
async function f() {
try {
await Promise.reject(出错了);
} catch(e) {
}
return await Promise.resolve(hello world);
三、案例
采用async/await有诸多好处,这里例举两个前端最常用的东西(ajax发送请求)来直观的感受呵呵采用async/await带来的便捷之处。
1. 传统的Ajax请求
//创建异步第一类
var xhr = new XMLHttpRequest();
//设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端
xhr.open(GET,http://www.atguigu.com);
//注册事件 onreadystatechange 状态改变就会初始化
xhr.onreadystatechange = function () {
//假如能够进到这个判断 说明 数据 完美的回来了,因此请求的页面是存在的
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(ajax.responseText); //输出相应的内容
}
}
//发送请求
ajax.send();
2. 用promise封装Ajax
采用promise可以更方便管理异步请求。promise可以用在单个或多个ajax请求,在多个请求当中可以指定请求的顺序。话不多说,上标识符:
function sendAjax(url) {
let xhr = new XMLHttpRequest()
return new Promise(function (resolve, reject) {
xhr.open(GET, url)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.responseText) // 成功执行 resolve
} else {
reject() // 失败执行 reject
}
}
}
xhr.send()
})
}
let p1 = sendAjax(http://www.atguigu.com)
p1.then(function (data) {
console.log(成功了)
console.log(data)
}, function () {
console.log(失败了)
})
let p2 = sendAjax(http://www.atguigu.com)
p2.then(function (data) {
console.log(成功了)
console.log(data)
}, function () {
console.log(失败了)
})
3. async/await
采用async/await可以处理promise拉艾初始化过长问题,async/await可以让他们同步书写请求冗余,看起来更舒服:
// 假设有这么两个情况:
// 现有两个A请求,然后B请求依赖A请求回到的数据,C请求依赖B请求回到的数据…
// 假如是promise写
post(A, data)
.then(res1 => post(B, res1))
.then(res2 => post(C, res2))
.then(res3 => post(D, res3))
.then(res4 => post(E, res4))
…
// 换成async/await写
async handler() {
let a = await post(A, data)
let b = await post(B, a)
let c = await post(C, b)
let d = await post(D, c)
…
}
总结
async/await 可以直接拿到 Promise 的结论,可以代替 then() 方法和回调表达式。可以取代拉艾初始化,是回调地狱的终极解决方案。缺点是状况为 rejected 的 Promise 示例,会放出异常,所以需要写在 try…catch结构中防止出错。