Skip to content

Promise实现 #7

@liang520

Description

@liang520
/**
 * 关于promise的实现,需要实现以下功能
 *
 * function fn1(resolve,reject){
 *        setTimeout(function(){
 *             console.log('步骤一')
 *             resolve(1)
 *         },500)
 * }
 * function fn2(resolve,reject){
 *         setTimeout(function(){
 *             console.log('步骤二')
 *             resolve(2)
 *         },200)
 * }
 *
 * new Promise(fn1).then(function(val){
 *     console.log(val)
 *     return new Promise(fn2)
 * }).then(function(val){
 *     console.log(val)
 *     return 33;
 * }).then(function(val){
 *     console.log(val)
 * })
 *
 */

//第一版基础实现

// /**
//  * 实现promise类
//  * @param {function} fn 传给promise的构造函数
//  */
// function Promise(fn) {
//   //定义回调方法变量
//   var callback;

//   //写then方法的
//   this.then = function(done) {
//     callback = done;
//   };
//   /**
//    * resolve之后,执行回调的成功的值
//    */
//   function resolve() {
//     callback();
//   }
//   fn(resolve);
// }

//第二版基础实现
//一个promise的then可以有多个

// function Promise(fn) {
//   var promise = this;
//   value = null;
//   promise._resolve = []; //回调的队里

//   this.then = function(onFulfilled) {
//     //将回调一步一步塞入队里里面
//     promise._resolve.push(onFulfilled);
//     return this;
//     //then之后需要链式调用
//   };

//   function resolve(value) {
//     //将resolve执行改成异步过程
//     setTimeout(function() {
//       promise._resolve.forEach(function(callback) {
//         //将resolve的值,传入每个回调里面
//         callback(value);
//       });
//     }, 0);
//   }
//   fn(resolve);
// }

/**
 * 此处执行
 * promise(fn(resolve)=>{
 *  resolve()
 * }).then((val)=>{
 *  console.log(val)
 * })
 *
 * 按照上面的写法,先执行resolve,此时是队列then注入的方法为空,
 * 需要对resolve做一次异步处理
 */

//引入promise状态

// function Promise(fn) {
//   var promise = this;
//   promise._resolve = [];
//   value = null;
//   promise._status = "PENDING";
//   this.then = function(onFulfilled) {
//     //状态为pending的时候,插入到队里
//     if (promise._status === "PENDING") {
//       promise._resolve.push(onFulfilled);
//       return this;
//     }
//     //否者直接执行
//     onFulfilled(value);
//     return this;
//   };
//   function resolve(value) {
//     setTimeout(function() {
//       //resolve之后,状态修改
//       promise._status = "FULFILLED";
//       promise._resolve.forEach(function(callback) {
//         value = callback(value);
//         //接受then之后执行的回调返回的数据
//       });
//     }, 0);
//   }
//   fn(resolve);
// }

/**
 * promise需要串行
 * 在当前promise状态为fufilled之后,then后会返回一个新的promise;
 * 需要串行调用
 */

function Promise(fn) {
  var value = null;
  promise = this;
  promise._resolve = [];
  promise._state = "PENDING";

  this.then = function(onFulfilled, onRejected) {
    //then方法也会返回一个promise
    return new Promise(function(resolve) {
      //重写处理函数
      function handle(value) {
        //判断是否是函数,then后面传入的
        var ret = isFunction(onFulfilled) ? onFulfilled(value) : value;
        //此处要考虑then里面返回的是一个promise对象
        if (ret && typeof ret["then"] == "function") {
          //执行返回的promise,取到值后,执行resolve
          ret.then(function(value) {
            resolve(value);
          });
        } else {
          //当前这个promise异步执行完成,执行resolve
          resolve(ret);
        }
      }

      function errorCallback(reason) {
        reason = (isFunction(onRejected) && onRejected(reason)) || reason;
        reject(reason);
      }

      if (promise._state == "PENDING") {
        promise._resolve.push(handle);
        promise._reject.push(errorCallback);
      } else if (promise._state == "FULFILLED") {
        //promise内部resolve(value)的值;在then后面调用then里面传入方法
        handle(value);
      } else if (promise._state == "REJECTED") {
        errorCallback(promise._reason);
      }
    });
  };

  function resolve(value) {
    setTimeout(function(value) {
      promise._state = "FULFILLED";
      promise._resolve.forEach(function(callback) {
        value = callback(value);
      });
    }, 0);
  }

  function reject(value) {
    setTimeout(function(value) {
      promise._state = "REJECTED";
      promise._reject.forEach(function(callback) {
        promise._reason = callback(value);
      });
    }, 0);
  }

  fn(resolve);

}

/**
 * Promise.resolve方法
 */
Promise.resolve = function(val) {
  return new Promise(function(resolve, reject) {
    resolve(val);
  });
};

/**
 * Promise.reject方法
 */
Promise.reject = function(val) {
  return new Promise(function(resolve, reject) {
    reject(val);
  });
};

Promise.all = function(promises) {
  if (Array.isArray(promises)) {
    throw new TypeError("yuo must pass an array to all");
  }
  //返回一个promise实例
  return new Promise(function(resolve, reject) {
    var result = [],
      len = promises.length,
      count = len;
    /**
     * 每一个promise执行成功之后,返回一个函数,接受promise之后的值
     * @param {number} index 数字
     */
    function resolver(index) {
      //返回一个函数,接受promise执行返回的值
      return function(value) {
        resolveAll(index, value);
      };
    }

    /**
     * 错误处理拒绝函数
     * @param {Object} reason 错误信息
     */
    function rejecter(reason) {
      reject(reason);
    }

    /**
     * 把执行成功的值,放到数组中
     * @param {number} index 返回值序号
     * @param {any} value 每一次的返回值
     */
    function resolveAll(index, value) {
      result[index] = value;
      if (--count == 0) {
        //当所有promise执行成功之后,resolve
        resolve(result);
      }
    }

    //依次执行每个promise
    for (var i = 0; i < len; i++) {
      promises[i].then(resolver(i), rejecter);
    }

  });
};

Promise.race = function(promises) {
  if (Array.isArray(promises)) {
    throw new TypeError("yuo must pass an array to all");
  }

  return new Promise(function(resolve, reject) {
    var len = promises.length;
    function resolver(value) {
      resolve(value);
    }
    function rejecter(reason) {
      reject(reason);
    }
    for (var i = 0; i < len; i++) {
      promises[i].then(resolver, rejecter);
    }
  });
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions