实现一个promise之完成对x的处理并测试


function resolvePromise(promise2, x, resolve, reject) {

 //如果promise和x是同一个对象,reject返回TypeError。

 if(promise2 === x){

  return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));

 };

 

 //如果被调用多次,只执行第一次,或略其它调用,如果x不是方法,是不会出现多次调用的。

 let called = false;

 //如果x是对象或者方法

 if((typeof x === 'object' && x !== null) || typeof x === 'function'){

  //如果x是一个对象或者函数,取值then = x.then,如果x.then出错,抛出错误执行reject。

  try{

   let then = x.then;

   //如果then是一个方法,用call改变this指向,把resolve和reject当作参数传递。

   // 成功参数y,失败参数r,并调用成功失败函数。

   if(typeof then === 'function'){

    then.call(x, (y) => {

     if(called) return;

     called = true;

     //如果return的是很多个promise,建议递归判断。

     resolvePromise(promise2, y, resolve, reject);

    }, (r) => {

     if(called) return;

     called = true;

     reject(r);

    })

   }else{

    //是对象,直接成功

    resolve(x);

   };

  }catch (e) {

   if(called) return;

   called = true;

   reject(e);

  }

 }else{

  //普通值,直接返回成功

  resolve(x);

 }

};



完成之后,promise官方推荐了一个测试方法,只有通过测试才算符合标准的promise:

https://github.com/promises-aplus/promises-tests



全局安装promises-aplus-tests,然后写上下面的代码,最后执行promises-aplus-tests promise.js

全部通过就算完成了。

Promise.defer = Promise.deferred = function () {

 let dfd = {};

 dfd.promise = new Promise((resolve, reject) => {

  dfd.resolve = resolve;

  dfd.reject = reject;

 });

 return dfd;

};

module.exports = Promise;

附上完成的代码,可以跑看看:

const PENDING = 'PENDING';

const FULFILLED = 'FULFILLED';

const REJECTED = 'REJECTED';



//处理返回结果

function resolvePromise(promise2, x, resolve, reject) {

 if(promise2 === x){

  return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));

 };

 

 let called = false;

 if((typeof x === 'object' && x !== null) || typeof x === 'function'){

  try{

   let then = x.then;

   if(typeof then === 'function'){

    then.call(x, (y) => {

     if(called) return;

     called = true;

     resolvePromise(promise2, y, resolve, reject);

    }, (r) => {

     if(called) return;

     called = true;

     reject(r);

    })

   }else{

    resolve(x);

   };

  }catch (e) {

   if(called) return;

   called = true;

   reject(e);

  }

 }else{

  resolve(x);

 }

};



class Promise {

 constructor(executor){

  this.state = PENDING;

  this.value = undefined;

  this.reason = undefined;

  this.onResolvedCallbacks = [];

  this.onRejectedCallbacks = [];

  

  let resolve = (value) => {

   if(this.state === PENDING){

    this.state = FULFILLED;

    this.value = value;

    this.onResolvedCallbacks.forEach(fn => fn());

   }

  };

  

  let reject = (reason) => {

   if(this.state === PENDING){

    this.state = REJECTED;

    this.reason = reason;

    this.onRejectedCallbacks.forEach(fn => fn());

   }

  };

  

  try{

   executor(resolve, reject);

  }catch (e) {

   reject(e);

  }

 }

 then(onFulfilled, onRejected){

  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : y => y;

  onRejected = typeof onRejected === 'function' ? onRejected : r => {throw r};

  let promise2 = new Promise((resolve, reject) => {

   if(this.state === FULFILLED){

    setTimeout(() => {

     try{

      let x = onFulfilled(this.value);

      resolvePromise(promise2, x, resolve, reject)

     }catch (e) {

      reject(e);

     };

    }, 0);

   };

   

   if(this.state === REJECTED){

    setTimeout(() => {

     try{

      let x = onRejected(this.reason);

      resolvePromise(promise2, x, resolve, reject)

     }catch (e) {

      reject(e);

     };

    }, 0);

   };

   

   if(this.state === PENDING){

    this.onResolvedCallbacks.push(() => {

     setTimeout(() => {

      try{

       let x = onFulfilled(this.value);

       resolvePromise(promise2, x, resolve, reject)

      }catch (e) {

       reject(e);

      };

     }, 0);

    });

    

    this.onRejectedCallbacks.push(() => {

     setTimeout(() => {

      try{

       let x = onRejected(this.reason);

       resolvePromise(promise2, x, resolve, reject)

      }catch (e) {

       reject(e);

      };

     }, 0);

    });

   };

  });

  return promise2;

 }

}



Promise.defer = Promise.deferred = function () {

 let dfd = {};

 dfd.promise = new Promise((resolve, reject) => {

  dfd.resolve = resolve;

  dfd.reject = reject;

 });

 return dfd;

};

module.exports = Promise;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值