1. Promise

1. 出现原因

因为回调地狱,Promise实现了异步链式调用。

2. 优缺点

  • 优点:
    1. 解决了回调地狱,实现了链式调用
  • 缺点:
    1. catch只能捕获到reject()抛出的错误
    2. 未完成一直处于pending状态,无法中途取消,无法确定执行到哪一步

3. 注意事项

4. 使用

Promise返回的还是Promise对象,可以一直(.then())链式调用下去。 Promise三种状态:pending、fulfilled、rejected

  1. function queryData(url) {
  2. // 里面逻辑决定是执行resolve还是reject。
  3. //resolve或reject会把这个异步返回值暂存下来,等着then去接收
  4. return new Promise(function (resolve, reject) {
  5. var xhr = new XMLHttpRequest();
  6. xhr.onreadystatechange = function () {
  7. if (xhr.readyState == 4 && xhr.status == 200) {
  8. // 处理正常的情况
  9. resolve(xhr.responseText);
  10. } else {
  11. // 处理异常情况
  12. reject('服务器错误');
  13. }
  14. };
  15. xhr.open('get', url);
  16. xhr.send(null);
  17. });
  18. }
  19. queryData('https://www.baidu.com/')
  20. .then(function (data) {
  21. console.log(data) //如果promise返回的是resolve状态,这里就打印xhr.responseText
  22. })
  23. .catch(function (data) {
  24. console.log(data) //如果promise返回的是reject状态,这里就打印‘服务器错误’
  25. })
  26. .finally(function () {
  27. console.log('finished') // 成功失败最后都会执行
  28. });


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” })

  1. <a name="WY4Vi"></a>
  2. ### 2. async/await
  3. <a name="XpDUi"></a>
  4. #### 1. 出现原因
  5. > Promise的then链问题,await 实现了异步代码同步写
  6. <a name="l06dw"></a>
  7. #### 2. 优缺点
  8. - **优点**
  9. - 使用try...catch可以捕获代码运行的所有错误,不仅仅是catch抛出的错误
  10. - **缺点**
  11. - 会阻塞代码,Promise不会
  12. <a name="AkUo6"></a>
  13. #### 3. 注意事项
  14. 1. await只能在带有async修饰的函数中使用
  15. 1. async函数返回值是Promise对象
  16. 1. await右侧表达式如果是Promise对象,await返回的是Promise成功的值;await右侧是普通表达式,相当于同步代码。
  17. 1. 不要滥用await,阻塞代码,可能会使性能降低
  18. <a name="laVhF"></a>
  19. #### 4. 使用
  20. 1. **基本使用**
  21. ```javascript
  22. async function test(){
  23. try{
  24. // queryData为上面封装的请求方法
  25. let res1 = await queryData("https://www.baidu.com/1")
  26. let res2 = await queryData("https://www.baidu.com/2")
  27. }catch(error){
  28. console.log(error)
  29. }
  30. }
  1. 循环中调用异步
    1. async function demo(arr) {
    2. for await (let i of arr) {
    3. handleDo(i);
    4. }
    5. }