Promise|青训营笔记

75 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第8天

1 Promise的使用(19)

1.1 什么是Promise

  • 我们确实可以请求函数得到的结果后,获取对应的回调,但是存在两个主要的问题:

    1. 我们需要自己来设计回调函数、回调函数的名称、回调函数的使用等;
    2. 对于不同的人、不同的框架设计出来的方案是不同的。那么我们必须去看别人的源码或文档,以便理解怎么使用;
  • Promise的API

    • Promise是一个类,可以翻译成承诺、期约;

    • 当我们需要给予调用者一个期约:待会儿我会给你回调数据时,就可以创建一个Promise对象;

    • 再通过new创建Promise对象时,我们需要传入一个回调函数,我们称之为executor

      1. 这个回调函数会被立即执行,并且给传入另外两个回调函数resolve、reject;
      2. 当我们调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数;
      3. 当我们调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数;
  • //传入的这个函数,被称为executor 它会被立即执行
    //传入两个回调函数
    //->resolve:回调函数,在成功时,回调resolve函数
    //->reject:回调函数,在失败时,回调reject函数
    const promise = new Promise((resolve, reject) => {
      console.log("Promise传入的函数被执行了");
      resolve("success message");
    })
    ​
    //在外面拿到的promies对象
    //在里面执行resolve后,外面的then方法会执行
    promise.then(() => {
      
    })
    //在里面执行reject后,外面catch会执行
    promise.catch(() => {
      
    })
    ​
    //合并写法 可以传递参数
    promise.then((res) => {
      //成功 相当于then
      //可以接收resolve传递的数据
      console.log(res);
    },() => {
      //与上面类似,也可传递参数
      //失败 相当于catch
    })
    
  • 什么是回调函数

    //钩子函数:hook 将函数传进来调用
    function foo(fn){
      fn();
    }
    foo(() => {
      
    });
    

    1.2 Promise的三种状态

  • new Promise((resolve,reject) => {
      //给Promise划分状态 这个地方属于executor
      //在此阶段,Promise的状态为pending(悬而未决)
      resolve();
    }).then(res => {
      //Promise中调用resolve回到此阶段
      //这个阶段被称为 fulfilled/resolved(固定 已敲定)
    },err => {
      //Promise中调用reject回到此阶段
      //这个阶段被称为rejected(已拒绝)
    })
    
  • 上面Promise使用过程中,我们可以将它划分为三个状态:

    1. 待定(pending):初始状态,既没有兑现,也没有被拒绝;

      当执行executor中的代码时,处于该状态;

    2. 已兑现(fulfilled):意味着操作成功完成;

      执行resolve时,处于该状态;

    3. 已拒绝(rejected):意味着操作失败;

      执行了reject时,处于该状态;

1.3 Promise的resolve参数

  • /**resolve(参数)
    *  1>普通的值或者对象;
    *  2>传入一个Promise;那么当前Promise的状态由传入Promise来决定
    *  3>传入一个对象,并且这个对象实现了then方法(并且这个对象实现了thenable接口)
    *  那么也会执行该then方法,并且由该then方法决定后续状态
    *///传入Promise对象
    const newPromise = new Promise((resolve,reject) =>{
      //这里是什么状态 下面就执行相应的函数
      reject(123);
    })
    new Promise((resolve,reject) => {
      //resolve("resolve message");(1)
      //2
      resolve(newPromise);
    }).then(res => {
      console.log("res:",res);
    },err => {
      console.log("err:",err);
    })
    ​
    //传入一个对象,这个对象有then方法
    new Promise((resolve,reject) => {
      const obj = {
        //then方法会自动执行,resolve和reject也会自动传递进来
        then: function(resolve,reject){
          //在这里决定接下来的状态
          reject("reject message");
        }
      }
      //会执行reject方法 
      resolve(obj);
    }).then(res => {
      console.log("res:",res);
    },err => {
      console.log("err:",err);
    })
    

    1.4 Promise的对象方法then

  • then方法是Promise对象上的一个方法:它其实是放在Promise的原型上的Promise.prototype.then

    //对象上的方法,需要先创建一个对象,在这个对象上调用
    const promise = new Promise();
    promise.then();
    //类方法,不用创建对象直接访问的方法叫做类方法
    Promise.all();
    ​
    class Promise {
      //对象方法
      then(){};
      //类方法
      static all(){};
    }
    
  • 同一个Promise可以被多次调用then方法,当我们resolve方法被回调时,所有的then方法传入的回调函数都会被调用

    console.log(Object.getOwnPropertyDescriptors(Promise.prototype));
    //finally、catch、then、constructorconst newPromise = new Promise((resolve,reject) =>{
      //下面then方法里传递的回调函数会在这里执行resolve的时候被回调
      resolve("hhh");
    })
    ​
    //newPromise.then(callback) 
    //同一个Promise可以被多次调用then方法 当我们resolve方法被回调时,所有的then方法传入的回调函数都会被调用
    //输出 res:hhh  res1:hhh res2:hhh
    newPromise.then((res) => {
      console.log("res:",res);
    }) 
    ​
    newPromise.then((res) => {
      console.log("res1:",res);
    }) 
    ​
    newPromise.then((res) => {
      console.log("res2:",res);
    }) 
    
    • then方法传入的回调函数是可以有返回值的,它的返回值是Promise

    • (1) 如果我们返回值是一个普通值,那么这个普通值被作为一个新的Promise的resolve值

      const newPromise = new Promise((resolve,reject) =>{
        resolve("hhh");
      })
      newPromise.then((res) => {
        return "aaaa";
      }) 
      ​
      //上面的代码底层相当于
      newPromise.then((res) => {
        return new Promise((resolve,reject) => {
          resolve("aaaa");
        })
      }) 
      ​
      //Promise的链式调用 能链式调用的原因是会产生新的Promise
      newPromise.then((res) => {
        return "aaaa";
      }).then(res => {
        //这里对应的是第二次new出来Promise的then方法  与上面的then方法不是同一个Promise的then方法 不会同时触发
        //输出res aaaa
        console.log("res",res);
        return "bbbb"
      }).then(res => {
        
      })
      
    • (2)如果我们返回的是一个Promise

       promise.then(res => {
         //返回值是一个Promise 会作为新的Promise的resovle的值
         //相当于往resolve里传递一个Promise参数 (上面已经提到)名 
         return new Promise((resolve,reject) => {
           setTimeout(() => {
             resolve(111);
           },3000);
         })
       }).then(res => {
         //3s后打印res 111
         console.log("res",res);
       })
      
    • promise.then(res => {
        const obj = {
          then:function(resolve,reject){
            resolve(2222);
          }
        }
        return obj;
        //这里返回的是一个新的Promise
      }).then(res => {
        //res:2222
        console.log("res:",res);
      })