Promise介绍(一)

161 阅读5分钟

一. promise对象的理解?

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例,里面保存着某个未来才会结束的事件。

Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。

promise对象里面接收一个函数作为参数,该函数的两个参数分别是reject和resolve,reject和resolve是js引擎提供的两个方法。

reject的作用是将promise对象的状态从‘未完成’变为‘失败’,在异步操作失败时调用,并将异步操作报错作为参数传递出去。

resolve的作用是当promise对象状态从“未完成”变为“成功”时调用,并将异步操作的结果作为参数传递出去。

promise对象里面还提供了.then 和 .catch的方法,分别用来接收promise对象返回的结果。

二.promise的特点?

1、自己身上有 all、reject、resolve 这几个方法

2、原型上有 then、catch 等方法 

3、一旦建立,就无法取消,这是它的缺点 ,

4、对象的状态不受外界影响。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

5、一旦状态改变,就不会再变,任何时候都可以得到这个结果。

三.promise对象的方法?

1.Promise.resolve()方法

解释: Promise.resolve()是promise对象上的方法 作用:当传入的是promise对象的时候,他会返回这个promise对象 可以快速得到一个promise对象 当resolve方法中传入的非promise对象的时候,他会返回成功的promise对象。

 const p = Promise.resolve(
    new Promise((resolve, reject) => {
      resolve(22);
    })
  );
 console.log(p);
2.Promise.reject方法

解释:作用:快速返回一个promise对象,返回的promise对象的状态是失败的 返回的promise对象的结果是当前传入的值

 const p = Promise.reject(
    new Promise((resolve, reject) => {
      resolve("succeed");
    })
  );
  console.log(p);
  console.log(Promise.reject(222));
3.Promise.all()方法

解释:总结: promise.all()方法的作用也是返回一个promise对象 promise.all()里面接收一个数组,数组里可以是多个promise对象。 当数组中传入的所有的promise对象都是成功状态的时候,返回的新的promise对象的状态是成功,值是当前传入的promise对象值的数组集合。 当数组中传入的promise对象中有一个状态是失败,返回的新的promise对象状态是失败,值是失败的那个promise的值 当数组中传入的promise对象中一个状态是padding,返回的新的promise对象状态是padding,值是undifind

  const p1 = Promise.resolve("succeed");
  const p2 = Promise.resolve("111");
  const p3 = Promise.reject(222);
  // const p4 = new Promise(()=>{
  // })
  const all = Promise.all([p1, p2, p3]);
  console.log(all);
4.Promise.race()方法

解释:promise.race()方法的作用是返回先执行的那个promise对象

  const p3 = Promise.reject(222);
  const p1 = Promise.resolve("succeed");
  const p2 = Promise.resolve("111");
  const p4 = new Promise(() => {
    setTimeout(() => {
      resolve(333);
    }, 1000);
  });
  const all = Promise.race([p4, p3, p2, p1]);
  console.log(all);

四.promise原型的方法?

1.Promise.prototype.then()方法

解释:then方法是定义在原型上的,供实例对象调用。当Promise实例状态改变时,通过调用then方法添加回调函数,then方法中接受两个回调函数,第一个是成功回调,第二个是失败回调。 调用then方法返回新的promise实例对象,当我们在当前的then方法后面再次.then的时候,此时后面的.then会等待上一次执行完成,并把执行的结果传入下一次.then的回调函数中,每一次的.then被执行promise的状态都会改变。

 const P = new Promise((resolve, reject) => {
    resolve(111);
  });
  console.log(P.then()); //Promise对象
  P.then(
    (res) => {
      console.log(res);  //111
      return res+111
    },
    (err) => {
      console.log(err);  
    }
  ).then((r)=>{
    console.log(r);  //222
  })

2.Promise.prototype.catch()方法

当promise实例的状态变成rejected的时候,这个时候catch方法可以捕获到这个错误,同时在then方法中如果抛出的错误也会被catch方法捕获。下面的代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

const p = new Promise((resolve, reject) => {
    reject("error");
    throw new Error("test");
  });
  p.then(
    (res) => {
      console.log(res);
    },
    (err) => {
      console.log(err); // error
      return x + 2;
    }
  ).catch((err) => {
    console.log(err); //x is not defined
  });

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。所以在书写时总是建议使用catch方法,而不是使用then方法的第二个参数。代码如下:

const p = new Promise((resolve, reject) => {
    resolve(111);
  });
  p.then((res) => {
    return res + 1;
  })
    .then((res) => {
      return res + a;
    })
    .then((res) => {
      return res + "x";
    })
    .catch((err) => {
      console.log(err); //a is not defined
    });
3.Promise.prototype.finally()方法

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。同时finally方法不接收任何参数,同时return出去的值,不会传入下一次的then方法中,这样使得它与promise的状态无关,不依赖于promise的执行结果。案例展示:

Promise.resolve(2)
    .then((res) => {
      setTimeout(() => {
        console.log(1);
      }, 2000);
      return res + x;
    })
    .catch((err) => {
      console.log(2);
      return err;
    })
    .then((res) => {
      console.log(3);
      console.log(res); //x is not defined
      return "aa";
    })
    .finally(() => {
      console.log(4);
      return "bb";
    })
    .then((res) => {
      console.log(res); //aa
    });
  //解释:执行的顺序是 2,3,"x is not defined",4,aa,1,

五.promise的基础封装

function MyPromise(callback) {
    //callback代表MyPromise中的回调函数
    this.PromiseState = "pending"; //默认状态pending
    this.PromiseResult = "undefined"; //默认是undefined
    const _this = this;
    callback(
      // 定义resolve,当执行了resolve函数就改变状态,并赋值
      function resolve(val) {
        //为了让promise对象只执行一次,状态改变就不会再变
        if (_this.PromiseState !== "pending") return;
        _this.PromiseState = "fulfilled";
        _this.PromiseResult = val;
        //异步的时候promise状态改变,执行resolveFn回调,同步的时候由于状态改变不会执行resolveFn回调
        if (_this.callback) {
          _this.callback.resolveFn(val);
        }
      },
      // 定义reject
      function reject(val) {
        if (_this.PromiseState !== "pending") return;
        _this.PromiseState = "rejected";
        _this.PromiseResult = val;
        if (_this.resolveFn) {
          _this.callback.rejectFn(val);
        }
      }
    );
  }
  //   添加then方法
  MyPromise.prototype.then = function (resolveFn, rejectFn) {
    //判断当前的promise状态是否成功
    if (this.PromiseState === "fulfilled") {
      resolveFn(this.PromiseResult);
    }
    if (this.PromiseState === "rejected") {
      resolveFn(this.PromiseResult);
    }
    //当promise是异步的时候,此时then方法中并不能拿到promise的值,可以使用callback对象存储下当前的then方法中的回调,当promise状态改变的时候再执行then方法
    if (this.PromiseState === "pending") {
      this.callback = {
        resolveFn,
        rejectFn,
      };
    }
  };
  const p = new MyPromise((resolve, reject) => {
    setTimeout(() => {
      resolve(222);
    }, 2000);
    // resolve(333);
    // reject(000)
  });
  p.then((res) => {
    console.log(res);
  });