尚硅谷-Promise

一、什么是Promise:

  1. Promise 是在 js 中进行异步编程的新解决方案。(以前旧的方案是单纯使用回调函数)

  2. 从语法来说,promise是一个构造函数。

  3. 从功能来说,promise对象用来封装一个异步操作,并且可以获得成功或失败的返回值。

  4. JS中的常见的异步操作:定时器、数据库操作,fs文件操作,AJAX中一般也是异步操作(也可以同步),回调函数可以理解为异步(不是严谨的异步操作)…等。剩下的都是同步处理

二、为啥使用Promise

  1. promise使用回调函数更灵活。旧的回调函数必须在启动异步任务前指定。
  2. promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至能在异步任务结束后指定多个)
  3. promise支持链式调用可以解决回调地狱问题。(回调地狱就是多层回调函数嵌套使用,就是套娃,这样就不利于阅读和异常处理。)

三、promise初体验:

效果:点击一个按钮,有30%概率显示中奖。
实现: 点击按钮后得到一个1到100间的随机数,小于等于30输出中奖,否则输出没中。期间用定时器模拟异步操作,在定时器里执行判断。

(1)基础的写法:

<button id="btn">click</button>
    <script>
        var btn = document.querySelector("#btn");
    // 该函数返回一个两数之间的随机整数,包括两个数在内
    function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
    }
    // 点击事件
     btn.addEventListener('click',function(){
         // 1秒的定时器,模拟异步操作
         setTimeout(() => {
             // 得到1到100间的一个数
             let n = getRandomIntInclusive(1, 100);
             if (n <= 30) {
                 alert('中奖喽');
             } else {
                 alert('没中奖');
             }
         }, 1000);
     })
    </script>

image-20210805155654952

(2)promise写法,在promise里封装一个异步操作。

    <script>
        var btn = document.querySelector("#btn");
    // 得到一个两数之间的随机整数,包括两个数在内
    function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值 
    }
    // 点击事件
     btn.addEventListener('click',function(){
         // 下面是promise ,resolve表示解决,reject表示拒绝 ,都是函数类型数据。
         const p = new Promise((resolve,reject) => {
             setTimeout(()=>{
                  let n = getRandomIntInclusive(1, 100);
                  if(n<=30){
                      resolve(); //将promise状态设为 “成功”
                  }else{
                      reject(); //将promise状态设为 “失败”
                  }
             },1000)
         });
         // 调用then方法
         p.then(()=>{
             // “成功”执行这步
            alert('中奖喽');
         },()=>{
             // “失败”执行这步
            alert('没中奖');
         })
     })

假如要在上面输出结果后加上选中的号码:
因为.then()里并不能直接获得 n,所以在resolve与reject里把n当结果值返回。

 // 点击事件
     btn.addEventListener('click',function(){
         // 下面是promise ,resolve表示解决,reject表示拒绝 ,都是函数类型数据。
         const p = new Promise((resolve,reject) => {
             setTimeout(()=>{
                  let n = getRandomIntInclusive(1, 100);
                  if(n<=30){
                      resolve(n); //将promise状态设为 “成功”,并把结果值n返回
                  }else{
                      reject(n); //将promise状态设为 “失败”,并把结果值n返回
                  }
             },1000)
         });
         // 调用then方法
         // value为值的意思,reason为理由的意思,都是形参
         p.then((value)=>{
             // “成功”执行
            alert(`中奖喽+${value}`);
         },(reason)=>{
             // “失败”执行
            alert('没中奖'+reason);
         })
     })

image-20210805155815424

四、promise体验Ajax请求

这是一个开源社区的api文档,有许多api。
效果:点击按钮获得一句名言在控制台输出。
基础写法:

 <script>
        var btn = document.querySelector("#btn");
    // 点击事件
      btn.addEventListener('click',function(){
         //创建对象
         const xhr = new XMLHttpRequest();
         //初始化
         xhr.open('GET',"http://poetry.apiopen.top/sentences");
         //发送
         xhr.send();
         //处理响应结果
         xhr.onreadystatechange = function(){
             if(xhr.readyState === 4){
                 if(xhr.status >=200 && xhr.status < 300){
                     //输出响应体
                     console.log(xhr.response);
                 }else{
                     //输出响应状态码
                     console.log(xhr.status);
                 }
             }
         }
     })
    </script>

image-20210805160326161

promise封装:

 // 点击事件
     btn.addEventListener('click',function(){
         const p = new Promise((resolve,reject) => {
              //创建对象
         const xhr = new XMLHttpRequest();
             //初始化
             xhr.open('GET', "http://poetry.apiopen.top/sentences");
             //发送
             xhr.send();
             //处理响应结果
             xhr.onreadystatechange = function () {
                 if (xhr.readyState === 4) {
                     if (xhr.status >= 200 && xhr.status < 300) {
                         //输出响应体
                        resolve(xhr.response);
                     } else {
                         //输出响应状态码
                         reject(xhr.status);
                     }
                 }
             }
         })
         p.then(value=>{
              console.log(value);
         },reason=>{
             //控制台输出警告信息
               console.warn(reason);
         })
     })

image-20210805160421129

若把接口写错:

image-20210805160434089

五、Promise封装AJAX请求

跟上一步差不多。就是把其封装在一个sendAJAX()的自定义函数里。


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);//promise状态变为fulfilled
                        } else {
                            //输出响应状态码
                            reject(xhr.status); //promise状态变为rejected
                        }
                    }
                }
            });
     }
    // 返回的就是promise对象
    // console.log(sendAJAX("http://poetry.apiopen.top/sentences"))
     sendAJAX("http://poetry.apiopen.top/sentences")
     .then(value=>{
              console.log(value);
         },reason=>{
             //控制台输出警告信息
               console.warn(reason);
         })
	
	    // 这样分开写也可以
        // .then(value=>{
        //     console.log(value);
        // }).catch(error=>{
        //     console.log(error);
        // })

六、promise的状态改变

promise状态表示实例对象的一个属性【PromiseState】。包括以下值:

(1)pending 未决定的
(2)resolved 或 fullfilled 成功
(3)rejected 失败

Promise对象的值表示实例对象的另一个属性【PromiseResult】。保存着对象【成功/失败】的结果。而其状态改变只有以下两种可能:

(1)pending 变为resolved( fullfilled)//调用resolve()
(2)pending 变为 rejected //调用reject()

注:一个promise对象只能改变一次,无论成功或失败都会有一个结果数据,成功的称为 value , 失败的称为 reason 。

image-20210805171112209

七、Promise基本流程图:

image-20210805172018979

执行then()方法返回的也是一个promise,所以可以链式调用

八、Promise的API使用:

1.Promise 的构造函数:Promise(executor){}

(1)executor 函数:执行器 (resolve,reject)=> {}。
(2)resolve 函数:内部定义成功时调用函数 value => {} 。
(3)reject 函数:内部定义失败时调用函数 reason => {} 。
注意:Promise内部会立即同步调用executor,异步操作在执行器里执行。

    <script>
        let p = new Promise((resolve, reject) => {
            // 同步调用
            console.log(1);
        })
        console.log(2);
    </script>

image-20210805173119911

2.Promise.prototype.then 方法: (onResolved, onRejected)=> {}

(1) onResolved 函数:成功的回调函数 (value) => {}
(2) onRejected 函数:失败的回调函数 (reason) => {}
注:指定用于得到成功value的成功回调和用于得到失败reason的失败回调是返回一个新的promise对象

3.Promise.prototype.catch方法: (onRejected) => {}

onRejected.函数: 失败的回调函数**(reason)=> {}**
注:只是失败的调用。then()的语法糖,相当于: then(undefined, onRejected)。

        let p = new Promise((resolve, reject) => {
            reject('error')
        })
        p.catch(reason=>{
            console.log(reason);
        })

image-20210805173848086

4.Promise.resolve 方法: (value)=> {}(函数对象的方法)

value: 成功的数据或promise对象
注:如果传入的参数为非Promise类 型的对象,则返回的结果为成功promise对象,如果传入的参数为Promise 对象,则参数的结果决定了resolve 的结果。

       let p1 = Promise.resolve(521);
        console.log(p1);

        let p2 = Promise.resolve(new Promise((resolve, reject) => {
            // resolve('成功')
            reject('失败')
        }))
        console.log(p2);

        // reject调用后 的报错处理
        p2.catch(reason => {
            console.log(reason);
        })

resolve(‘成功’):

image-20210805174956142

reject(‘失败):

image-20210805175249981

5.Promise.reject 方法: (reason) => {} (函数对象的方法)

reason: 失败的原因
注:无论传入啥只返回一个失败的promise对象。

        let p = Promise.reject(521)
        let p2 = Promise.reject(new Promise((resolve,reject)=>{
            resolve('失败的promise')
        }))
        console.log(p);
        console.log(p2);
        p.catch(reason=>{
            console.log(reason);
        });
        p2.catch(reason=>{
            console.log(reason);
        });

image-20210805185421008

6.Promise.all 方法: (promises)=> {}

promises: 包含n个promise的数组
注:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败。失败了返回那个失败值。

       let p1 = new Promise((resolve, reject) => {
            resolve('success')
        })
        let p2 = Promise.resolve('OK');
        // let p2 = Promise.reject('error')

        let p3 = Promise.resolve('Yeah')

        const result = Promise.all([p1, p2, p3])
        console.log(result); // 成功的promise对象,结果值就是三个promise它们成功的结果组成的数组
        result.then(value => {
            console.log(value);
        }, reason => {
            console.log(reason);
        })

所有promise都成功时的返回:

image-20210805190620004

其中存在失败的promise时的返回:

image-20210805190712797

7.Promise.race方法:(promises)=>{}

promises: 包含n个promise的数组
注:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态。

race就是比赛的意思

来一个例子:

 let p1 = new Promise((resolve,reject)=>{
          setTimeout(()=>{
              resolve('yes');
          },1000)
      })
      let p2 = Promise.resolve('success');
      let p3 = Promise.resolve('come');

      const result = Promise.race([p1,p2,p3]);
      console.log(result);

image-20210805191149284

九、使用Promise面临的关键问题:

1.如何改变 promise的状态?

(1) resolve(value): 如果当前是pending就会变为(fulfilled)resolved。
(2) reject(reason): 如果当前是pending就会变为rejected。
(3)抛出异常 throw :如果当前是pending就会变为rejected。

         let p1 = new Promise((resolve,reject)=>{
           //  resolve('success');
           //  reject('error');
            throw 'error'; // 或者抛出异常对象也可以
      })
      console.log(p1);
      p1.catch(reason=>{
          console.log(reason);
      })

image-20210805191847794

2. 一个 promise指定多个成功/失败回调函数,都会调用吗?

当promise改变为对应状态时都会调用。

 let p = new Promise((resolve,reject)=>{
            resolve('success');  // 这个不执行p的状态就不会改变,下面的回调函数就不会调用
      })
      // 第一次回调
      p.then(value=>{
          console.log("yes");
          alert(value); // success
      })
      // 第二次回调
      p.then(value=>{
          console.log("oh yes");
          alert(value); // success
      })

image-20210805191957287

3.改变 promise状态和指定回调函数谁先谁后?

指定回调-改变状态-执行回调

是指定回调先呢?还是改变状态先呢?

(1)都有可能, 正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调
(2)如何先改状态再指定回调?
①在执行 器中直接调用resolve(/reject();
②延迟更 长时间才调用then();
(3)什么时候才能得到数据?
①如果先指定的回调, 那当状态发生改变时,回调函数就会调用,得到数据
②如果先改变的状态, 那当指定回调时,回调函数就会调用,得到数据
4.promise.then()返回新的promise的结果状态由什么决定?
(1)简单表达: then()指定的回调函数执行的结果决定。
(2)详细表达:
*如果抛出异常, 新promise变为rejected, reaon为抛出的异常。
*如果返回的是非prormise的任意值,新promise变为resolved, value为返回的值。
*如果返回的是另一个新promise,此promise的结果就会成为新promise的结果。
        let p = new Promise((resolve, reject) => {
            resolve('success'); 
            // reject('No'); 
            //  throw 'oh no';
        });
        let result = p.then(value => {
           //console.log(value);   // fulilled  undefined 这个等于return undefined
           //return 123       //result 会变为fulfilled状态  promiseResult 为123
           // throw 'error' //result 会变为失败状态  promiseResult 为error
           // return Promise.reject('失败')  // rejected '失败'
           //   return new Promise((resolve,reject)=>{
               //reject(123)     //rejected 123
               //resolve(456)    //fulfilled 456
           })
           //return Promise.resolve('成功')   // fulfilled '成功'
        }, reason => {
            console.warn(reason);
        });
        console.log(result);
5.promise 如何串连多个操作任务?
(1) promise 的then()返回一个新的promise,可以看成then()的链式调用。
(2)通过then的链式调用串连多个同步/异步任务。
        let p = new Promise((resolve, reject) => {
            resolve("yes");
        })

        p.then(value => {
            console.log(value);
            return new Promise((resolve, reject) => {
                resolve("oh yes~");
            });
        }).then(value => {
            console.log(value); // on yes~  // 当前promise对象:fulfiled undefined
        }).then(value=>{
            console.log(value); // undefined
        })
输出结果:
yes
oh yes~
undefined
6.promise 的异常穿透。
(1)当使用promise的then链式调用时,可以在最后指定失败的回调。
(2)前面任何操作出 了异常,都会传到最后失败的回调中处理。
 let p =new Promise((resolve,reject) => {
         setTimeout(()=>{
            resolve("yes");
         },1000);
     })
     p.then(value => {  // 这里执行
          throw 'oh No';
     }).then(value => { // 这里不执行
          console.log("123");
     }).then(value => { //这里不执行
          console.log("456");
     }).catch(reason=>{  // 抛出异常后直接跳到这里
         console.warn(reason);
     })
输出结果:
oh No
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("yes");
            }, 1000);
        })
        p.then(value => {
            console.log(value); //yes
            // throw 'oh No';
            console.log('aa');
        }).then(value => {
            console.log(value); //undefined//上一个promise状态成功rusult:undefined
            console.log("123");
        }).then(value => { 
            console.log(value); // undefined
            console.log("456");
        }).catch(reason => {
            console.warn(reason);
        })
7.中断promise链
(1)当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数。
(2)办法:在回调函数中返回一个pendding状态的promise对象。

未中断:

 let p =new Promise((resolve,reject) => {
         setTimeout(()=>{
            resolve("yes");
         },1000);
     })
     p.then(value => {
          console.log("789");
     }).then(value => {
          console.log("123");
     }).then(value => {
          console.log("456");
     }).catch(reason=>{
         console.warn(reason);
     })

输出结果:
789
123
456

中断:

 let p =new Promise((resolve,reject) => {
         setTimeout(()=>{
            resolve("yes");
         },1000);
     })
     p.then(value => {
          console.log("789");
          return new Promise(()=>{});//状态没有改变,后续回调不会执行
     }).then(value => {
          console.log("123");
     }).then(value => {
          console.log("456");
     }).catch(reason=>{
         console.warn(reason);
     })
输出结果:
789

十、Promise的自定义封装

1.初始化解构搭建
 // 自定义函数 Promise  executor:执行器函数
     function Promise(executor){
		
     }
     // 添加then方法
     Promise.prototype.then = function(onResolved,onRejected){
         
     }

注:prototype (原型对象)属性使您有能力向对象添加属性和方法。(这里涉及构造函数和原型链的知识)

2.搭建resolve与reject函数
 // 自定义函数Promise
     function Promise(executor){
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){

          }
          //自定义reject函数
          function reject(data){

          }
          //同步调用【执行器函数】
          executor(resolve,reject);          
     }
     // 添加then方法
     Promise.prototype.then = function(onResolved,onRejected){
         
     }
3.实现resolve与reject函数
 // 自定义函数Promise
     function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolved 
             //改变结果值属性
             that.PromiseResult =data;
          }
          //自定义reject函数
          function reject(data){
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
          }
          //同步调用【执行器函数】
          executor(resolve,reject);          
     }
     // 添加then方法
     Promise.prototype.then = function(onResolved,onRejected){
         
     }
4.throw抛出异常改变状态

采用 try{ }catch(){ } 与throw一起使用。

// 自定义函数Promise
 function Promise(executor){
      //添加状态属性与结果值属性
      this.PromiseState = 'pending';
      this.PromiseResult = null;
       //保存实例对象的this值
       const that = this;
      //自定义resolve函数,名字不一定用resolve
      function resolve(data){
         //改变状态属性
         that.PromiseState = 'fulfilled';  // 或者 resolve 
         //改变结果值属性
         that.PromiseResult =data;
      }
      //自定义reject函数
      function reject(data){
          //改变状态属性
         that.PromiseState = 'rejected';  
        //改变结果值属性
         that.PromiseResult =data;
      }

      try{
      //同步调用【执行器函数】
      executor(resolve,reject);
      }catch(e){
          //更改Promise对象为失败
          reject(e);
      }
      
 }
 // 添加then方法
 Promise.prototype.then = function(onResolved,onRejected){
     
 }

注:throw语句抛出一个错误。

5.设定Promise对象状态只能修改一次

加个判断就好。

// 自定义函数Promise
     function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function(onResolved,onRejected){
         
     }
6. then()方法执行回调:
  // 自定义函数Promise
     function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function(onResolved,onRejected){
         //如果Promise状态为fulfilled回调这个函数
         if(this.PromiseState === 'fulfilled'){
             //将结果值传入
            onResolved(this.PromiseResult);
         }
         //如果Promise状态为rejected回调这个函数
         if(this.PromiseState === 'rejected'){
             //将结果值传入
            onRejected(this.PromiseResult);
         }
     }
 
7.执行异步任务回调:

异步任务一般先回调才改变状态。所以第6步的代码执行顺序就无法执行异步回调,解决如下:

// 自定义函数Promise
 function Promise(executor){
      //添加状态属性与结果值属性
      this.PromiseState = 'pending';
      this.PromiseResult = null;
      // 定义callback属性,保存pending状态的回调函数
      this.callback = {};
       //保存实例对象的this值
       const that = this;
      //自定义resolve函数,名字不一定用resolve
      function resolve(data){
        //判断状态是否修改过
        if(that.PromiseState !== 'pending') return;
         //改变状态属性
         that.PromiseState = 'fulfilled';  // 或者 resolve 
         //改变结果值属性
         that.PromiseResult =data;
          //异步任务成功后执行回调函数
          if(that.callback.onResolved){
             that.callback.onResolved(data);
         }
      }
      //自定义reject函数
      function reject(data){
         //判断状态是否修改过,改过就直接返回
        if(that.PromiseState !== 'pending') return;
          //改变状态属性
         that.PromiseState = 'rejected';  
        //改变结果值属性
         that.PromiseResult =data;
         //异步任务失败后执行回调函数
         if(that.callback.onRejected){
             that.callback.onRejected(data);
         }
      }

      try{
      //同步调用【执行器函数】
      executor(resolve,reject);
      }catch(e){
          //更改Promise对象为失败
          reject(e);
      }
      
 }
 // 添加then方法
 Promise.prototype.then = function(onResolved,onRejected){
     //如果Promise状态为fulfilled回调这个函数
     if(this.PromiseState === 'fulfilled'){
         //将结果值传入
        onResolved(this.PromiseResult);
     }
     //如果Promise状态为rejected回调这个函数
     if(this.PromiseState === 'rejected'){
         //将结果值传入
        onRejected(this.PromiseResult);
     }
      //如果Promise状态为pending,保存回调函数
      if(this.PromiseState === 'pending'){
        this.callback = {
            onResolved: onResolved,
            onRejected: onRejected
        }
     }
 }
8.能执行多个回调:

用第7步写法指定多个回调时,最后一个then回调会覆盖掉前面的,解决如下,把保存回调函数的callbacks变为一个数组:

// 自定义函数Promise
     function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function(onResolved,onRejected){
         //如果Promise状态为fulfilled回调这个函数
         if(this.PromiseState === 'fulfilled'){
             //将结果值传入
            onResolved(this.PromiseResult);
         }
         //如果Promise状态为rejected回调这个函数
         if(this.PromiseState === 'rejected'){
             //将结果值传入
            onRejected(this.PromiseResult);
         }
          //如果Promise状态为pending,保存回调函数
          if(this.PromiseState === 'pending'){
            this.callbacks.push({
                onResolved: onResolved,
                onRejected: onRejected
            })
         }
     }

forEach()方法

9.同步任务 then()的返回结果:

就是在then()里有实现有结果返回:

const result = p.then(value => {
          console.log(value);
     },reason => {
         console.warn(reason);
     }) 
console.log(result);

解决:

// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
            return new Promise((resolve, reject) => {
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    try {
                        //获取回调函数执行结果
                        let result = onResolved(this.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    //将结果值传入
                    onRejected(this.PromiseResult);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: onResolved,
                        onRejected: onRejected
                    })
                }
            })
        }

注:instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

10.异步任务 then()的返回结果:

(´ཀ`」 ∠)
用第9步执行异步任务return返回的会是pending状态。
解决:

// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
            return new Promise((resolve, reject) => {
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    try {
                        //将结果值传入
                        let result = onResolved(this.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    //将结果值传入
                    onRejected(this.PromiseResult);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            try {
                                //执行成功回调函数
                                let result = onResolved(that.PromiseResult);
                                //判断
                                if (result instanceof Promise) {
                                    result.then(v => {
                                        resolve(v);
                                    }, r => {
                                        reject(r);
                                    })
                                } else {
                                    resolve(result);
                                }
                            } catch (e) {
                                reject(e);
                            }
                        },
                        onRejected: function () {
                            try {
                                //执行成功回调函数
                                let result = onRejected(that.PromiseResult);
                                //判断
                                if (result instanceof Promise) {
                                    result.then(v => {
                                        resolve(v);
                                    }, r => {
                                        reject(r);
                                    })
                                } else {
                                    resolve(result);
                                }
                            } catch(e){
                                reject(e);
                            }
                        }
                    })
                }
            })
        }
11. 完善then()方法与优化:
// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
        }
12. 实现catch方法与异常穿透:
// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
         //判断回调参数是否存在
         if(typeof onRejected !== 'function'){
             onRejected = reason =>{
                 throw reason;
             }
         }
         if(typeof onResolved !== 'function'){
             onResolved = value => value;
         }
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
        }
//添加catch 方法
     Promise.prototype.catch = function(onRejected){
         return this.then(undefined,onRejected);
     }

注:typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

13.封装Promise.resolve方法
// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
         //判断回调参数是否存在
         if(typeof onRejected !== 'function'){
             onRejected = reason =>{
                 throw reason;
             }
         }
         if(typeof onResolved !== 'function'){
             onResolved = value => value;
         }
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
        }
//添加catch 方法
     Promise.prototype.catch = function(onRejected){
         return this.then(undefined,onRejected);
     }
//添加resolve方法
Promise.resolve = function(value){
    //返回promise对象
    return new Promise((resolve,reject) =>{
       if(value instanceof Promise){
            value.then(v=>{
               resolve(v);
            },r=>{
               reject(r);
            })
       }else{
            resolve(value);
       }
    })
}

注:instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
实践一下:

 let p = Promise.resolve(new Promise((resolve,reject)=>{
          reject('_(´ཀ`」 ∠)_');
      }));
      console.log(p);

image-20210806163815311

14. 封装Promise.reject方法:

无论传入啥只返回一个失败的promise对象。

// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
         //判断回调参数是否存在
         if(typeof onRejected !== 'function'){
             onRejected = reason =>{
                 throw reason;
             }
         }
         if(typeof onResolved !== 'function'){
             onResolved = value => value;
         }
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
        }
//添加catch 方法
     Promise.prototype.catch = function(onRejected){
         return this.then(undefined,onRejected);
     }
//添加resolve方法
Promise.resolve = function(value){
    //返回promise对象
    return new Promise((resolve,reject) =>{
       if(value instanceof Promise){
            value.then(v=>{
               resolve(v);
            },r=>{
               reject(r);
            })
       }else{
            resolve(value);
       }
    })
}
//添加reject方法
Promise.reject = function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason);
    });
}

15. 封装Promise.all方法:

返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败。失败了返回那个失败值。

// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data){
            //判断状态是否修改过
            if(that.PromiseState !== 'pending') return;
             //改变状态属性
             that.PromiseState = 'fulfilled';  // 或者 resolve 
             //改变结果值属性
             that.PromiseResult =data;
              //异步任务成功后执行回调函数
              that.callbacks.forEach(item=>{
                  item.onResolved(data);
              })
          }
          //自定义reject函数
          function reject(data){
             //判断状态是否修改过,改过就直接返回
            if(that.PromiseState !== 'pending') return;
              //改变状态属性
             that.PromiseState = 'rejected';  
            //改变结果值属性
             that.PromiseResult =data;
             //异步任务失败后执行回调函数
            that.callbacks.forEach(item=>{
                item.onRejected(data);
            })
          }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
         //判断回调参数是否存在
         if(typeof onRejected !== 'function'){
             onRejected = reason =>{
                 throw reason;
             }
         }
         if(typeof onResolved !== 'function'){
             onResolved = value => value;
         }
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved);
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    callback(onRejected);
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
        }
//添加catch 方法
     Promise.prototype.catch = function(onRejected){
         return this.then(undefined,onRejected);
     }
//添加resolve方法
Promise.resolve = function(value){
    //返回promise对象
    return new Promise((resolve,reject) =>{
       if(value instanceof Promise){
            value.then(v=>{
               resolve(v);
            },r=>{
               reject(r);
            })
       }else{
            resolve(value);
       }
    })
}
//添加reject方法
Promise.reject = function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason);
    });
}
//添加all方法
Promise.all = function(promises){
    return new Promise((resolve,reject) => {
        //添加变量
        let count = 0;
        // 存放成功结果数组
        let arr =[];
        //遍历全部
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                //能进到证明其为成功
                count++;
                //保存成功结果
                arr[i]=v;
                //如果全部成功
                if (count === promises.length) {
                    //状态为成功
                    resolve(arr);
                }
            }, r => {
                 //能进到证明其为失败
                reject(r);
            });
        }
    });
}

试一下:

        let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('111')
            }, 1000)

        })
        const p2 = Promise.resolve('222')
        const p3 = Promise.resolve('333')

        let result = Promise.all([p1, p2, p3])
        console.log(result);

结果:

image-20210806165443175

16. 封装Promise.race方法:

返回一个新的promise,第一个完成的promise的结果状态改变的就是最终的结果状态。
上面重复的代码就不写上了:

//添加race方法
Promise.race = function(promises){
    return new Promise((resolve,reject) => {
        //遍历全部
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                    //能进到证明其为成功
                    //状态为成功
                    resolve(v);
                }, r => {
                 //能进到证明其为失败
                reject(r);
            })
         }
      });
    }

试一下:

        let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('111')
            }, 1000)

        })

        const p2 = Promise.resolve('222')
        const p3 = Promise.resolve('333')
        let result = Promise.race([p1, p2, p3])
        console.log(result);

运行结果:注意跟传入的数组元素顺序也有关,若传入[p1,p3,p2],从左到右执行,结果为p3

运行结果:

image-20210806170038504

17.回调函数异步执行:

原生promise的执行顺序:

        let p1 = new Promise((resolve, reject) => {
              resolve('ok')
              console.log(111);
        })

        p1.then(value=>{
            // console.log(value);
            console.log(222);
        })
        console.log(333);
输出结果:
111
333 
222

上面回调函数还是同步执行的,要让 then()回调函数异步执行。
添加定时器模仿异步操作:

// 自定义函数Promise
function Promise(executor){
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data) {
        //判断状态是否修改过
        if (that.PromiseState !== 'pending') return;
        //改变状态属性
        that.PromiseState = 'fulfilled';  // 或者 resolve 
        //改变结果值属性
        that.PromiseResult = data;
        //异步任务成功后执行回调函数
        setTimeout(() => {
            that.callbacks.forEach(item => {
                item.onResolved(data);
            })
        });
    }
    //自定义reject函数
    function reject(data) {
        //判断状态是否修改过,改过就直接返回
        if (that.PromiseState !== 'pending') return;
        //改变状态属性
        that.PromiseState = 'rejected';
        //改变结果值属性
        that.PromiseResult = data;
        //异步任务失败后执行回调函数
        setTimeout(() => {
            that.callbacks.forEach(item => {
                item.onRejected(data);
            })
        });
    }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
          
     }
     // 添加then方法
     Promise.prototype.then = function (onResolved, onRejected) {
         const that = this;
         //判断回调参数是否存在
         if(typeof onRejected !== 'function'){
             onRejected = reason =>{
                 throw reason;
             }
         }
         if(typeof onResolved !== 'function'){
             onResolved = value => value;
         }
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    setTimeout(()=>{
                        callback(onResolved);
                    });
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    setTimeout(()=>{
                        callback(onRejected);
                    });
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
        }
//添加catch 方法
     Promise.prototype.catch = function(onRejected){
         return this.then(undefined,onRejected);
     }
//添加resolve方法
Promise.resolve = function(value){
    //返回promise对象
    return new Promise((resolve,reject) =>{
       if(value instanceof Promise){
            value.then(v=>{
               resolve(v);
            },r=>{
               reject(r);
            })
       }else{
            resolve(value);
       }
    })
}
//添加reject方法
Promise.reject = function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason);
    });
}
//添加all方法
Promise.all = function(promises){
    return new Promise((resolve,reject) => {
        //添加变量
        let count = 0;
        // 存放成功结果数组
        let arr =[];
        //遍历全部
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                //能进到证明其为成功
                count++;
                //保存成功结果
                arr[i]=v;
                //如果全部成功
                if (count === promises.length) {
                    //状态为成功
                    resolve(arr);
                }
            }, r => {
                 //能进到证明其为失败
                reject(r);
            });
        }
    });
}
//添加race方法
Promise.race = function(promises){
    return new Promise((resolve,reject) => {
        //遍历全部
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                    //能进到证明其为成功
                    //状态为成功
                    resolve(v);
                }, r => {
                 //能进到证明其为失败
                reject(r);
            })
         }
      });
    }
18.class版本封装:

最终封装:

class Promise{
    //构造方法
    constructor(executor) {
          //添加状态属性与结果值属性
          this.PromiseState = 'pending';
          this.PromiseResult = null;
          // 定义callback属性,保存pending状态的回调函数
          this.callbacks = [];
           //保存实例对象的this值
           const that = this;
          //自定义resolve函数,名字不一定用resolve
          function resolve(data) {
        //判断状态是否修改过
        if (that.PromiseState !== 'pending') return;
        //改变状态属性
        that.PromiseState = 'fulfilled';  // 或者 resolve 
        //改变结果值属性
        that.PromiseResult = data;
        //异步任务成功后执行回调函数
        setTimeout(() => {
            that.callbacks.forEach(item => {
                item.onResolved(data);
            })
        });
    }
    //自定义reject函数
    function reject(data) {
        //判断状态是否修改过,改过就直接返回
        if (that.PromiseState !== 'pending') return;
        //改变状态属性
        that.PromiseState = 'rejected';
        //改变结果值属性
        that.PromiseResult = data;
        //异步任务失败后执行回调函数
        setTimeout(() => {
            that.callbacks.forEach(item => {
                item.onRejected(data);
            })
        });
    }

          try{
          //同步调用【执行器函数】
          executor(resolve,reject);
          }catch(e){
              //更改Promise对象为失败
              reject(e);
          }
    }
    //then方法封装
    then(onResolved,onRejected){
        const that = this;
         //判断回调参数是否存在
         if(typeof onRejected !== 'function'){
             onRejected = reason =>{
                 throw reason;
             }
         }
         if(typeof onResolved !== 'function'){
             onResolved = value => value;
         }
            return new Promise((resolve, reject) => {
                //封装重复的部分
                function callback(type){
                    try {
                        //将结果值传入
                        let result = type(that.PromiseResult);
                        //判断
                        if (result instanceof Promise) {
                            //如果是Promise对象
                            result.then(v => {
                                resolve(v);
                            }, r => {
                                reject(r);
                            })
                        } else {
                            //结果对象状态为【成功】
                            resolve(result);
                        }
                    } catch (e) {
                        reject(e);
                    }
                }
                //如果Promise状态为fulfilled回调这个函数
                if (this.PromiseState === 'fulfilled') {
                    setTimeout(()=>{
                        callback(onResolved);
                    });
                }
                //如果Promise状态为rejected回调这个函数
                if (this.PromiseState === 'rejected') {
                    setTimeout(()=>{
                        callback(onRejected);
                    });
                }
                //如果Promise状态为pending,保存回调函数
                if (this.PromiseState === 'pending') {
                    this.callbacks.push({
                        onResolved: function () {
                            callback(onResolved);
                        },
                        onRejected: function () {
                            callback(onRejected);
                        }
                    })
                }
            })
    }
    //catch 方法
    catch(onRejected){
         return this.then(undefined,onRejected);
     }
    //resolve方法
    static resolve(value){
    //返回promise对象
    return new Promise((resolve,reject) =>{
       if(value instanceof Promise){
            value.then(v=>{
               resolve(v);
            },r=>{
               reject(r);
            })
       }else{
            resolve(value);
       }
    })
}
    //reject方法
    static reject(reason){
    return new Promise((resolve,reject)=>{
        reject(reason);
    });
}
    //all方法
    static all(promises) {
        return new Promise((resolve, reject) => {
            //添加变量
            let count = 0;
            // 存放成功结果数组
            let arr = [];
            //遍历全部
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v => {
                    //能进到证明其为成功
                    count++;
                    //保存成功结果
                    arr[i] = v;
                    //如果全部成功
                    if (count === promises.length) {
                        //状态为成功
                        resolve(arr);
                    }
                }, r => {
                    //能进到证明其为失败
                    reject(r);
                });
            }
        });
    }
    //race方法
    static race(promises) {
        return new Promise((resolve, reject) => {
            //遍历全部
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v => {
                    //能进到证明其为成功
                    //状态为成功
                    resolve(v);
                }, r => {
                    //能进到证明其为失败
                    reject(r);
                })
            }
        });
    }

}

十一、async函数

MDN文档

1.函数的返回值为promise对象。
2.promise对象的结果由async函数执行的返回值决定。
3.其实跟 then()方法返回结果是一模一样的。
1.返回一个非Promise对象,返回值是resolve。
 async function main(){
             return '123';
          }
          let res = main();
          console.log(res);

image-20210806174612441

2.如果返回是一个Promise对象,由返回结果决定:
 async function main(){
             return new Promise((resolve,reject)=>{
                 reject('NO');
             });
          }
          let res = main();
          console.log(res);

image-20210806174722193

3.抛出异常也是失败:
        async function main() {
            return new Promise((resolve,reject)=>{
                throw 'error'
            })
        }
        let result = main()
        console.log(result);

image-20210806175219561

十二、await表达式

MDN文档

1.await右侧的表达式一般为promise对象,但也可以是其它的值。
2.如果表达式是promise对象,await返回的是promise成功的值。
3.如果表达式是其它值,直接将此值作为await的返回值。

注意:

1.await 必须写在async函数中,但async 函数中可以没有await 。
2.如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理。
1.右侧为promise对象:
 async function works(){
             let p = new Promise((resolve,reject)=>{
                 resolve('oh yes')
             })
             let res = await p;
             console.log(res);
         }
         works();

结果:
oh yes

2.右侧为其它值:
  async function works(){
             let p = new Promise((resolve,reject)=>{
                 resolve('oh yes')
             })
           //  let res = await p;
           let res = await 100;
             console.log(res);
         }
         works();

结果:
100

3.如果promise是失败状态:
 async function works(){
             let p = new Promise((resolve,reject)=>{
                // resolve('oh yes')
                reject('err');
             })          
            try{
                let res = await p;
            }catch(e){
                console.log(e);
            }
         }
         works();

image-20210806180034696

回顾一下async函数的返回值问题

        async function works() {
            let p = new Promise((resolve, reject) => {
                // resolve('oh yes')
                reject('err');
            })
            try {
                let res = await p;
            } catch (e) {
                console.log(e);
            }
        }
        let result = works();
        console.log(result);

运行结果:(async函数没有返回值,所以promise结果是undefined)

image-20210806180318433

十三、async与await结合发送AJAX请求

效果: 点击按钮获取一句名言。

    <button id="btn">点击获取段子</button>
    <script>
        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)
                        }
                    }
                }
            })
        }

        let btn = document.querySelector('#btn')
        btn.addEventListener('click', async function () {
            // 获取段子信息
            try {
                let duanzi = await sendAJAX("http://poetry.apiopen.top/sentences")
                console.log(duanzi);
            } catch (e) {
                console.log(e);
            }
        })
    </script>

image-20210806195726076

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值