js promise实现笔记

在开发web前端应用的时候,经常会碰到回调地狱,promise是一个很好的解决办法,基本上所有的浏览器都自行实现了promise对象,但是我想自己实现一个简单的promise then链,然后在网上看到了这篇博文的实现方式,研究许久才明白其运行方式,遂写个博文做个记录以备后日不时之需(代码为上述网站提供的代码,在此仅供参考学习之用)

代码:

/********************
    *Promise构造函数接收一个异步处理的函数fn为参数,
    *fn接收一个resolve函数和一个reject函数为参数
    *fn运行成功则运行resolve,否则运行reject
    *resolve,reject都可接受一个参数,运行完毕后Promise.then的参数callback
    *Promise.then为promise的一个属性,是一个带callback函数作为参数的函数
    *Promise.then应该返回一个新的promise,其fn应为返回这一次的done函数的匿名函数
********************/

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function MyPromise(fn) {
  // store state which can be PENDING, FULFILLED or REJECTED
  var state = PENDING;

  // store value once FULFILLED or REJECTED
  var value = null;

  // store sucess & failure handlers
  var handlers = [];

  function fulfill(result) {
    state = FULFILLED;
    value = result;
    handlers.forEach(handle);
    handlers = [];
  }

  function reject(error) {
    state = REJECTED;
    value = error;
    handlers.forEach(handle);
    handlers = [];
  }

  function resolve(result) {
    try {
      var then = getThen(result);
      if (then) {
        doResolve(then.bind(result), resolve, reject)
        return
      }
      fulfill(result);
    } catch (e) {
      reject(e);
    }
  }

  function handle(handler) {
    if (state === PENDING) {
      handlers.push(handler);
    } else {
      if (state === FULFILLED &&
        typeof handler.onFulfilled === 'function') {
        handler.onFulfilled(value);
      }
      if (state === REJECTED &&
        typeof handler.onRejected === 'function') {
        handler.onRejected(value);
      }
    }
  }

  this.done = function (onFulfilled, onRejected) {
    // ensure we are always asynchronous
    // setTimeout(function () {
      handle({
        onFulfilled: onFulfilled,
        onRejected: onRejected
      });
    // }, 0);
  }

  doResolve(fn, resolve, reject);

  this.then = function(onFulfilled, onRejected) {
    var self = this;
    return new MyPromise(function(resolve, reject) {
      self.done(function(result) {
        console.log(7);
        if (typeof onFulfilled === 'function') {
          try {
            resolve(onFulfilled(result));
          } catch (ex) {
            reject(ex);
          }
        } else {
          resolve(result);
        }
      }, function (error) {
        if (typeof onRejected === 'function') {
          try {
            resolve(onRejected(error));
          } catch (ex) {
            reject(ex);
          }
        } else {
          reject(error);
        }
      });
    });
  }
}

function getThen(value) {
    var t = typeof value;
    if (value && (t === 'object' || t === 'function')) {
        var then = value.then;
        if (typeof then === 'function') {
        return then;
        }
    }
    return null;
}

function doResolve(fn, onFulfilled, onRejected) {
  var done = false;
  try {
    fn(function (value) {
      if (done) return
      done = true
      onFulfilled(value)
    }, function (reason) {
      if (done) return
      done = true
      onRejected(reason)
    })
  } catch (ex) {
    if (done) return
    done = true
    onRejected(ex)
  }
}

流程图

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值