Promise


Promise 从入门到自定义

第 1 章:Promise 的理解和使用

1.1. Promise 是什么?

1.1.1. 理解

  1. 抽象表达:
    • Promise 是一门新的技术(ES6 规范)
    • Promise 是 JS 中进行异步编程的新解决方案 备注:旧方案是单纯使用回调函数
  2. 具体表达:
  • 从语法上来说: Promise 是一个构造函数
  • 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值

1.1.2. promise 的状态改变

Promise 初体验

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>基本使用</title>
    <link
      crossorigin="anonymous"
      href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>

  <body>
    <div class="container">
      <h2 class="page-header">Promise 初体验</h2>
      <button class="btn btn-primary" id="btn">点击抽奖</button>
    </div>
    <script>
      //生成随机数
      function rand(m, n) {
        return Math.ceil(Math.random() * (n - m + 1)) + m - 1;
      }
      /**
            点击按钮,  1s 后显示是否中奖(30%概率中奖)
                若中奖弹出    恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券
                若未中奖弹出  再接再厉
        */
      //获取元素对象
      const btn = document.querySelector("#btn");
      //绑定单击事件
      btn.addEventListener("click", function () {
        //定时器
        // setTimeout(() => {
        //     //30%  1-100  1 2 30
        //     //获取从1 - 100的一个随机数
        //     let n = rand(1, 100);
        //     //判断
        //     if(n <= 30){
        //         alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券');
        //     }else{
        //         alert('再接再厉');
        //     }
        // }, 1000);

        //Promise 形式实现
        // resolve 解决  函数类型的数据
        // reject  拒绝  函数类型的数据
        const p = new Promise((resolve, reject) => {
          console.log("mmmmmmm");
          setTimeout(() => {
            console.log("ssssssss");
            //30%  1-100  1 2 30
            //获取从1 - 100的一个随机数
            let n = rand(1, 100);
            //判断
            if (n <= 30) {
              resolve(n); // 将 promise 对象的状态设置为 『成功』
            } else {
              reject(n); // 将 promise 对象的状态设置为 『失败』
            }
          }, 1000);
        });

        console.log(p);
        //调用 then 方法
        // value 值
        // reason 理由
        p.then(
          (value) => {
            alert(
              "恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券, 您的中奖数字为 " +
                value
            );
          },
          (reason) => {
            alert("再接再厉, 您的号码为 " + reason);
          }
        );
      });
    </script>
  </body>
</html>

结果展示:

chrome_koTpoOyRup

Promise 相关练习:

Promise 实践练习-fs 模块

//
const fs = require("fs");

//回调函数 形式
// fs.readFile('./resource/content.txt', (err, data) => {
//     // 如果出错 则抛出错误
//     if(err)  throw err;
//     //输出文件内容
//     console.log(data.toString());
// });

//Promise 形式
let p = new Promise((resolve, reject) => {
  fs.readFile("./resource/content.tx", (err, data) => {
    //如果出错
    if (err) reject(err);
    //如果成功
    resolve(data);
  });
});

//调用 then
p.then(
  (value) => {
    console.log(value.toString());
  },
  (reason) => {
    console.log(reason);
  }
);

Promise 实践练习-AJAX 请求

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise 封装 AJAX</title>
    <link
      crossorigin="anonymous"
      href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container">
      <h2 class="page-header">Promise 封装 AJAX 操作</h2>
      <button class="btn btn-primary" id="btn">点击发送 AJAX</button>
    </div>
    <script>
      //接口地址 https://api.apiopen.top/getJoke
      //获取元素对象
      const btn = document.querySelector("#btn");

      btn.addEventListener("click", function () {
        //创建 Promise
        const p = new Promise((resolve, reject) => {
          //1.创建对象
          const xhr = new XMLHttpRequest();
          //2. 初始化
          xhr.open("GET", "https://api.apiopen.top/getJoke");
          //3. 发送
          xhr.send();
          //4. 处理响应结果
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
              //判断响应状态码 2xx
              if (xhr.status >= 200 && xhr.status < 300) {
                //控制台输出响应体
                resolve(xhr.response);
              } else {
                //控制台输出响应状态码
                reject(xhr.status);
              }
            }
          };
        });
        //调用then方法
        p.then(
          (value) => {
            console.log(value);
          },
          (reason) => {
            console.warn(reason);
          }
        );
      });
    </script>
  </body>
</html>

Promise 封装练习-fs 模块

/**
 * 封装一个函数 mineReadFile 读取文件内容
 * 参数:  path  文件路径
 * 返回:  promise 对象
 */
function mineReadFile(path) {
  return new Promise((resolve, reject) => {
    //读取文件
    require("fs").readFile(path, (err, data) => {
      //判断
      if (err) reject(err);
      //成功
      resolve(data);
    });
  });
}

mineReadFile("./resource/content.txt").then(
  (value) => {
    //输出文件内容
    console.log(value.toString());
  },
  (reason) => {
    console.log(reason);
  }
);

Promise 封装 AJAX 操作

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise封装AJAX操作</title>
  </head>
  <body>
    <script>
      /**
       * 封装一个函数 sendAJAX 发送 GET AJAX 请求
       * 参数   URL
       * 返回结果 Promise 对象
       */
      function sendAJAX(url) {
        return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          xhr.responseType = "json";
          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);
              }
            }
          };
        });
      }

      sendAJAX("https://api.apiopen.top/getJok").then(
        (value) => {
          console.log(value);
        },
        (reason) => {
          console.warn(reason);
        }
      );
    </script>
  </body>
</html>

2-Promise-API

1-Promise 的 API-then 和 catch

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise API</title>
  </head>

  <body>
    <script>
      //
      let p = new Promise((resolve, reject) => {
        // ** 同步调用
        console.log(111);
        //修改 promise 对象的状态
        reject("error");
      });

      console.log(222);

      //执行 catch 方法
      p.catch((reason) => {
        console.log(reason);
      });
    </script>
  </body>
</html>

运行结果:

image-20220801100433368

2-Promise 的 API-resolve

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise API - resolve</title>
  </head>

  <body>
    <script>
      //
      let p1 = Promise.resolve(521);
      //如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
      //如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
      let p2 = Promise.resolve(
        new Promise((resolve, reject) => {
          // resolve('OK');
          reject("Error");
        })
      );
      console.log(p2);
      p2.catch((reason) => {
        console.log(reason);
      });
    </script>
  </body>
</html>

image-20220801100604430

3-Promise 的 API-reject

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise API - reject</title>
  </head>

  <body>
    <script>
      let p = Promise.reject(521);
      let p3 = Promise.reject(
        new Promise((resolve, reject) => {
          resolve("OK");
        })
      );
      console.log(p);
      console.log(p3);
    </script>
  </body>
</html>

image-20220801100812375

4-Promise 的 API-all

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise API - all</title>
  </head>

  <body>
    <script>
      let p1 = new Promise((resolve, reject) => {
        resolve("OK");
      });
      let p2 = Promise.resolve("Success");
      // let p2 = Promise.reject('Error');
      let p3 = Promise.resolve("Oh Yeah");

      //
      const result = Promise.all([p1, p2, p3]);

      console.log(result);
    </script>
  </body>
</html>

image-20220801101058805

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise API - all</title>
  </head>

  <body>
    <script>
      let p1 = new Promise((resolve, reject) => {
        resolve("OK");
      });
      // let p2 = Promise.resolve('Success');
      let p2 = Promise.reject("Error");
      let p3 = Promise.reject("Oh Yeah");

      //
      const result = Promise.all([p1, p2, p3]);

      console.log(result);
    </script>
  </body>
</html>

image-20220801101207087

5-Promise 的 API-race

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise API - race</title>
  </head>
  <body>
    <script>
      let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("OK");
        }, 1000);
      });
      let p2 = Promise.resolve("Success");
      let p3 = Promise.resolve("Oh Yeah");

      //调用
      const result = Promise.race([p1, p2, p3]);

      console.log(result);
    </script>
  </body>
</html>

image-20220801101328251


文章作者: Liu Yuan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Liu Yuan !
—— 评论区 ——
  目录