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')
  );
}

  

 

转载于:https://www.cnblogs.com/NKnife/p/8806490.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值