promise对象

1.promise的含义

promise是异步编程一种解决方案,比传统的解决方案--回调函数和事件更合理、更强大。所谓promise简单说就是一个容器,里面保存某个未来才会结束的事件结果。

从语法上说,promise是一个对象,可以从他获取异步操作的消息。promise提供统一的API,各种异步操作都可以使用同样的方法进行处理。

2.promise对象有两个特点

1)对象的状态不受外界影响。有3种状态:pending(进行中)、fulfilled(已成功)、rejeced(已失败)。只有异步操作的结果可以决定当前是哪种状态,任何其他操作无法改变这种状态。

2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。promise对象的状态改变,只能两种可能:从pending变为fulfilled,从pending变为resjected.主要这两种情况发生状态就凝固不会再变了,并一直保持这种结果,这时就成为resoved(已定型)/如果改变已经发生了,再对promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果错过了再去监听,将不会得到结果。

有了promise对象,就可以将异步操作以同步操作的流程表达出来,避免使用层层嵌套的回调函数。此外对象提供统一的接口,使得异步操作更加容易。

3.promise对象缺点

1)无法取消,一旦新建立即执行,无法中途取消

2)如果不设置回调函数,内部抛出错误不会反映到外部

3)处于pending状态无法判断处于哪个阶段,是刚开始还是已经完成。

基本用法

ES6规定,Promise对象是一个构造函数,用来生产promise实例。

promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject。他们是两个函数,由javascript引擎提供,不用自己部署。

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

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

在promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

then方法可以接受两个回调函数作为参数。

第一个是promise对象的状态变为resolved时调用,第二个是状态变为rejected时调用,第二个回调函数是可选的,不一定提供。他们都接受promise对象传出的值作为参数。

 

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

手写一个promise

 

const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";

function MyPromise(fn) {
  // 保存初始化状态
  var self = this;

  // 初始化状态
  this.state = PENDING;

  // 用于保存 resolve 或者 rejected 传入的值
  this.value = null;

  // 用于保存 resolve 的回调函数
  this.resolvedCallbacks = [];

  // 用于保存 reject 的回调函数
  this.rejectedCallbacks = [];

  // 状态转变为 resolved 方法
  function resolve(value) {
    // 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变
    if (value instanceof MyPromise) {
      return value.then(resolve, reject);
    }

    // 保证代码的执行顺序为本轮事件循环的末尾
    setTimeout(() => {
      // 只有状态为 pending 时才能转变,
      if (self.state === PENDING) {
        // 修改状态
        self.state = RESOLVED;

        // 设置传入的值
        self.value = value;

        // 执行回调函数
        self.resolvedCallbacks.forEach(callback => {
          callback(value);
        });
      }
    }, 0);
  }

  // 状态转变为 rejected 方法
  function reject(value) {
    // 保证代码的执行顺序为本轮事件循环的末尾
    setTimeout(() => {
      // 只有状态为 pending 时才能转变
      if (self.state === PENDING) {
        // 修改状态
        self.state = REJECTED;

        // 设置传入的值
        self.value = value;

        // 执行回调函数
        self.rejectedCallbacks.forEach(callback => {
          callback(value);
        });
      }
    }, 0);
  }

  // 将两个方法传入函数执行
  try {
    fn(resolve, reject);
  } catch (e) {
    // 遇到错误时,捕获错误,执行 reject 函数
    reject(e);
  }
}

MyPromise.prototype.then = function(onResolved, onRejected) {
  // 首先判断两个参数是否为函数类型,因为这两个参数是可选参数
  onResolved =
    typeof onResolved === "function"
      ? onResolved
      : function(value) {
          return value;
        };

  onRejected =
    typeof onRejected === "function"
      ? onRejected
      : function(error) {
          throw error;
        };

  // 如果是等待状态,则将函数加入对应列表中
  if (this.state === PENDING) {
    this.resolvedCallbacks.push(onResolved);
    this.rejectedCallbacks.push(onRejected);
  }

  // 如果状态已经凝固,则直接执行对应状态的函数

  if (this.state === RESOLVED) {
    onResolved(this.value);
  }

  if (this.state === REJECTED) {
    onRejected(this.value);
  }
};

  

posted @ 2020-06-10 15:04  蜗牛不是涡流  阅读(563)  评论(0编辑  收藏  举报