Promise 用es5的基础实现

只实现 then 和 catch

function promise(fn) {
  var state = 'pending';
  // 声明函数
  var nowResolve = function (arg) { return arg };
  var nowReject = function (arg) { return arg };
  var nextResolve = function (arg) { return arg };
  var nextReject = function (arg) { return arg };
  var catchReject = function (e) { throw e + ' (in promise)' };

  promise.prototype.then = function (res, rej) {
    typeof res === 'function' ? nowResolve = res : '';
    typeof rej === 'function' ? nowReject = rej : '';
    // return 新的对象
    return new promise(function (resolve, reject) {
      // then 中 return 的值传递给下一个 resolve/reject
      nextResolve = resolve;
      // 如果 then 中有 reject 回调函数, 则将 return 的值传递给下一个 resolve, 否则继续传递给reject
      nextReject = typeof rej === 'function' ? resolve : reject;
      // 捕获错误的回调函数
      catchReject = reject;
    });
  }

  promise.prototype.catch = function (fn) {
    return this.then(null, fn);
  }

  // 传值到下一个回调,以及异常捕获
  function tryCatchFn(state, arg) {
    try {
      state === 'fulfilled' ? nextResolve(nowResolve(arg)) : nextReject(nowReject(arg));
    } catch (e) {
      catchReject(e);
    }
  }

  function callback(value) {
    return function (arg) {
      if (state !== 'pending') { return; }
      state = value;
      // 如果传参是 promise 构造器生成的对象,传递对象 resolve 的值
      if (arg instanceof promise) {
        arg.then(function (res) {
          tryCatchFn('fulfilled', res);
        }, function (rej) {
          tryCatchFn('rejected', rej);
        });
        return;
      }
      // 如果是普通的传值,setTimeout 是为了 resolve/reject 同步代码的时候正常工作
      setTimeout(function () {
        tryCatchFn(state, arg);
      });
    }
  }

  fn(
    callback('fulfilled'),
    callback('rejected')
  );
}

  

 

posted @ 2018-04-12 11:25  _NKi  阅读(319)  评论(0编辑  收藏  举报