Promise

123 阅读2分钟

1、Promise的含义:

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大,是能够解决回调地狱的一种方式。

Promise的两个特性:

  • 对象的状态不会受外界影响,它的状态值由异步函数的结果决定;
  • 对象的状态值一旦确定将不会改变,并且任何时候都能获取,Promise状态的改变,状态值由pending变为resolved或者rejected;

Promise的三个缺点:

  • Promise构造函数一旦创建便会立即执行,中途无法取消;
  • Promise如果没有设置回调函数,内部发生错误时无法传递到函数外部,外部(异步)函数会继续执行;
  • Promise的状态值为pending时,是无法判断目前执行到哪一个阶段,是刚开始执行还是即将结束。

Promise的基本用法:

const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise.prototype.then()方法

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数。

手写简易版Promise:

 const PENDING = 'pending',
       RESOLVED = 'resolved',
       REJECTED = 'rejected';

  function MyPromise(fn){
      const that = this;
      that.state = PENDING;
      that.value = null;
      that.resolveCallback = [];
      that.rejectCallback = [];

      function resolve(value){
          if(that.state = PENDING){
              that.state = RESOLVED;
              that.value = value;
              that.resolveCallback.map(cb => cb(that.value));         
          }  
      }

      function reject(value){
          if(that.state = PENDING){
              that.state = REJECTED;
              that.value = value;
              that.rejectCallback.map(cb => cb(that.value));
          }
      }

      try {
          fn(resolve, reject);
      }catch(err){
          reject(err);
      }
  }

  MyPromise.prototype.then = function(onResolved, onRejected){
      const that = this;
      onResolved = typeof onResolved === 'Function' ?  onResolved : v => v;
      onRejected = typeof onRejected === 'Function' ?  onRejected : r => {
          throw r;
      };

      if(that.state === PENDING){
          that.resolveCallback.push(onResolved);
          that.rejectCallback.push(onRejected);
      }
      if(that.state === RESOLVED){
          onResolved(that.value)
      }
      if(that.state === REJECTED){
          onRejected(that.value)
      }
  }