1. Promise
1. 出现原因
因为回调地狱,Promise实现了异步链式调用。
2. 优缺点
- 优点:
- 解决了回调地狱,实现了链式调用
- 缺点:
- catch只能捕获到reject()抛出的错误
- 未完成一直处于pending状态,无法中途取消,无法确定执行到哪一步
3. 注意事项
4. 使用
Promise返回的还是Promise对象,可以一直(.then())链式调用下去。 Promise三种状态:pending、fulfilled、rejected
function queryData(url) {// 里面逻辑决定是执行resolve还是reject。//resolve或reject会把这个异步返回值暂存下来,等着then去接收return new Promise(function (resolve, reject) {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {// 处理正常的情况resolve(xhr.responseText);} else {// 处理异常情况reject('服务器错误');}};xhr.open('get', url);xhr.send(null);});}queryData('https://www.baidu.com/').then(function (data) {console.log(data) //如果promise返回的是resolve状态,这里就打印xhr.responseText}).catch(function (data) {console.log(data) //如果promise返回的是reject状态,这里就打印‘服务器错误’}).finally(function () {console.log('finished') // 成功失败最后都会执行});
Promise内置方法:**
- p.then() 得到异步任务的正确结果
- p.catch() 获取异常信息
- p.finally() 成功与否都会执行(尚且不是正式标准)
- Promise.all() 所有任务都执行完成才能得到结果
- Promise.race() 只要有一个任务完成就能得到结果 ```javascript // queryData:封装的请求函数,返回Promise对象 var p1 = queryData(‘http://localhost:3000/a1‘); var p2 = queryData(‘http://localhost:3000/a2‘); var p3 = queryData(‘http://localhost:3000/a3‘); Promise.all([p1,p2,p3]).then((result) => { // all 中的参数 [p1,p2,p3] 和 返回的结果一 一对应[“HELLO TOM”, “HELLO JERRY”, “HELLO SPIKE”] console.log(result) //[“HELLO TOM”, “HELLO JERRY”, “HELLO SPIKE”] })
Promise.race([p1,p2,p3]).then((result) => { // 由于p1执行较快,Promise的then()将获得结果’P1’。p2,p3仍在继续执行,但执行结果将被丢弃。 console.log(result) // “HELLO TOM” })
<a name="WY4Vi"></a>### 2. async/await<a name="XpDUi"></a>#### 1. 出现原因> Promise的then链问题,await 实现了异步代码同步写<a name="l06dw"></a>#### 2. 优缺点- **优点**- 使用try...catch可以捕获代码运行的所有错误,不仅仅是catch抛出的错误- **缺点**- 会阻塞代码,Promise不会<a name="AkUo6"></a>#### 3. 注意事项1. await只能在带有async修饰的函数中使用1. async函数返回值是Promise对象1. await右侧表达式如果是Promise对象,await返回的是Promise成功的值;await右侧是普通表达式,相当于同步代码。1. 不要滥用await,阻塞代码,可能会使性能降低<a name="laVhF"></a>#### 4. 使用1. **基本使用**```javascriptasync function test(){try{// queryData为上面封装的请求方法let res1 = await queryData("https://www.baidu.com/1")let res2 = await queryData("https://www.baidu.com/2")}catch(error){console.log(error)}}
- 循环中调用异步
async function demo(arr) {for await (let i of arr) {handleDo(i);}}
