Promise(手动实现)

本文详细解析了Promise的基本使用方法,包括创建、静态方法(all、any、race、reject和resolve)、then和catch的用法,以及Promise的实现原理,涉及状态管理、构造函数、原型函数和辅助函数的编写。通过实例演示了如何一步步构建Promise对象及其关键函数。
摘要由CSDN通过智能技术生成

参考链接

Promise 基本用法及实现原理
ECMAScript 6 入门
Promise实现原理(附源码)

1. Promise

1.1 Promise 的基本使用
1.1.1 创建
let mp = new Promise( function( resolve, reject ) {
    
} );
let mp = Promise.resolve( value );
let mp = Promise.reject( value );
1.1.2 静态方法
  • Promise.all( iterable )

    返回值:新的promise对象,对象的值为所有promise对象结果组成的数组。(结果都是成功的)

    所有iterable参数里面的promise对象都成功才会触发,
    一旦有一个失败,就将错误信息作为返回promise对象的值,此时promise对象状态为失败。

  • Promise.allSettled( iterable )
    返回值:新的promise对象,对象值为所有promise对象组成的数组。(结果有成功,也有失败的)
    在所有promise 完成之后,将所有结果作为一个集合返回。

  • Promise.any( iterable )
    返回值:返回一个新的promise对象,对象的值为第一个成功的promise对象的值。

    有一个成功就会返回。

    如果没有成功的,又没有catch那么会终止函数,后面的内容不会执行。

    (使用nodejs12版本,提示TypeError: Promise.any is not a functionmdn显示nodejs16版本以后支持,更新了16.9.1之后,可以使用)

    ( async function() {
      console.log('aaa')
      await Promise.any([]).then(val => console.log(val))
      console.log('bbb')
    } )()
    
  • Promise.race( iterable )
    返回值: 返回已给新的promise对象,值为第一个成功或失败的promise对象的值。
    有一个成功或失败就会执行。

  • Promise.reject( reason )
    返回值:返回一个状态为失败的promise对象,值为reason

  • Promise.resolve( value )
    返回值:返回一个状态为成功的promise对象,值为value

函数职能
Promise.all所有Promise对象全部成功之后
Promise.allSettled所有Promise对象全部执行之后(无论成功失败)
Promise.any所有Promise对象有一个成功就行
Promise.race所有Promise对象有一个执行完成就行(无论成功失败)
Promise.reject返回一个rejected状态的Promise对象
Promise.resolve返回一个fulfilled状态的Promise对象
1.1.3 then、catch
let mp = new Promise( fucntion( res, rej ) {
                     res(1);
                     } )
mp.then( function( val ) { //... 
					 }, 
         function( err ) { //... 
					 } );

then,接受两个函数,在Promise对象执行成功之后,执行第一个函数;对象状态为失败的时候,执行第二个函数。

mp.catch( function( err ) {
    //...
} )

catch,接受一个参数,在失败之后,捕获错误信息。
reject抛出的错误不会被try/catch捕捉到,需要Promisecatch函数。

catch返回的状态时fulfilled

mp.catch( function(){} )
// == mp.then( undefined, function() {} )
// 不同的地方在于catch可以放在后面,捕获这一整条Promise链的错误
1.1.4 finally
mp.finally( function() {} )

finally不会接收参数,返回的Promise对象为

1.2 Promise实现
1.2.1 确定成员函数和成员变量
  • 状态
    Promise对象包括三个状态,fulfilled,rejected,pending

    状态只能从pending变为fulfilled,以及从pendng变为rejected

    而且状态在改变之后,不能再改变。

    new function( (res, rej) => {
        res(1);
        res(2);
        rej(3);	// 只有res(1)是有效的,在res(1)之后,状态变为fulfilled,不可再改变
    } )
    
  • 拟实现的函数

    • constructor
    • res
    • rej
    • then
    • finally
    • all
    • any
    • race
    • isFunction
1.2.2 准备工作

MP: MyPromise
MP是最终需要实现的Promise对象的构造函数。

  1. createPropDes: 创建属性描述符

    // 创建属性描述符
    function createPropDes( value, writable = false, enumerable = true, configurable = false ) {
      return {
        value:        value,
        writable:     writable,
        enumerable:   enumerable,
        configurable: configurable
      }
    }
    
1.2.3 定义状态

Object.defineProperties给对象添加属性,同时规定属性的描述符。

// 状态
const state = {};

Object.defineProperties( state, {
  Pending:  createPropDes( 'Pending' ),
  Resolved: createPropDes( 'Resolved' ),	// 准确说,是fulfilled
  Rejected: createPropDes( 'Rejected' )
} )
1.2.4 定义MP的结构

首先,我们确定,一个Promise对象包含两个属性,一个是值,一个是状态,此外包含一系列成员函数。

然后,我们可以将两个属性放在MP的构造函数里面,将公共函数放在原型上,以达到复用效果。

整体结构如下(具体内容在后面):

// 原型
var MpPrototype = {};
Object.defineProperties( MpPrototype, {
    // 定义可复用函数
	// ...
})
// MP
function MP() {
    // 定义状态、值等等属性
    // ...
}
// 给MP添加原型
MP.prototype = MpPrototype;
// 使用
let mp = new MP(...){
	// ...                
}
1.2.5 实现MpPrototype
1.2.5.1 实现resolve和reject函数

正常Promise的使用流程:

let mp = new Promise( function(res, rej){
                     res(1)
                     } )

可见,Promise构造函数结构的参数是一个函数,该函数在构造函数执行的时候被调用。

模拟流程如下:

function A( fn ){
    fn();
}
let mp = new A( function(){...} );

再观察传入的参数,该函数接收两个参数,这两个参数也是函数,这两个函数传入的值,最终决定了Promise的值,同时,调用res决定Promise状态为fulfilled,调用rej决定Promise状态为rejected

模拟流程如下:

function A( fn ){
    this.res = new function() {};
    this.rej = new function() {};
    fn( res, rej );
}
let mp = new A( function( res, rej ){
    res(1);
    //...
} );

再进一步,给A添加状态_state和值_val

function A( fn ){
    this._val = undefined;
    this._state = state.Pending;	// 默认为Pending状态
    
    this.res = new function( val ) {
        if ( this._state != state.Pending )	// 仅Pending状态可以改变
            return;
        this._state = state.Resolved;
        this._val = val;
    };
    this.rej = new function( err ) {
        if ( this._state != state.Pending )	// 仅Pending状态可以改变
            return;
        this._state = state.Rejected;
        this._val = err;
    };
    fn( res.bind(this), rej.bind(this) );
}
let mp = new A( function( res, rej ){
    res(1);
    //...
} );

细节需要注意,res或者rej被调用的时候,修改的是Promise的值,this指向的是Promise对象。
但是在fn内调用的时候,res没有调用者,this指向global,严格模式下this指向undefined
所以需要bind使得this始终指向Promise对象。

结束模拟,实具体实现一下resrej函数:

// 原型
var MpPrototype = {};
Object.defineProperties( MpPrototype, {
    // resolve
    res: createPropDes( function( val ) {
        let fn = () => {
            if ( !this.isPending() ) {
            	return;
            }
            this._state = state.Resolved;	// 成功状态
      		this._val = val;				// this 指向 MP 对象
        }
        setTimeout( ()=>{
            fn();
        }, 0 )
    } ),
    // reject
    rej: createPropDes( function( err ) {
        let fn = () => {
            if ( !this.isPending() ) {
            	return;
            }
            this._state = state.Rejected;	// 失败状态
      		this._val = err;				// this 指向 MP 对象
        }
        setTimeout( ()=>{
            fn();
        }, 0 )
    } ),
})

注:

这里大量使用箭头函数,参考《JavaScript高级程序设计(第四版)》的第300页,

在箭头函数中,this引用的是定义箭头函数的上下文。

我们可以先快进到后续的步骤,对于resrej函数,最后的调用情况应该形如:

function MP() {
    this.res(...)
}

我们需要让this始终指向MPMyPromise)对象。

首先,在MP函数内使用this.resres是一个标准函数,《高程(第四版)》第300页:

在标准函数中,this引用的是把函数当成方法调用的上下文对象。

简单来说,标准函数中this指向调用者,(如果没有直接的调用者,this指向全局上下文,浏览器中指向windownodejs全局中输出this结果为{},函数中输出this结果为global对象;在严格模式下this指向undefined),箭头函数中this始终指向定义时候的函数(的上下文)。

那么res内部this的指向为MP对象。
在此时,定义了fn函数类型变量,由于fn是箭头函数,fnthis指向定义时候的上下文,所以fn也指向MP对象,所以:

this._state = state.Rejected;	// 失败状态
this._val = err;				// this 指向 MP 对象

都是对MP对象的属性的设置。

1.2.5.2 实现then

首先,明确一点,then函数接受两个参数,一个成功状态的回调函数,一格式失败状态的回调函数。
通常我们使用Promise是这个情况的:

let a = new Promise((res, rej)=>{res(1)});
a.then( function(val) {
    // ...
}, function(err) {
    // ...
} )

我们可以知道,Promise对象从resolvereject函数获得的值,最终传递给了then函数的两个回调函数。
所以,可以先进行简单模拟:

function MP() {
    this.then = function( onResolved, onRejected ){
        if ( 成功 ) {
        	onResolved( this._val );	// MP 对象的值传递给onResolved函数作为参数
        }
        else if ( 失败 ) {
            onRejected( this._val );	// MP 对象的值传递给onRejected函数作为参数
        }
        else if ( 还没出结果 ) {
            // ...
        }
    }
}
  1. 如果成功了
    此时需要执行onResolved函数,并且将onResolved函数的返回值作为返回的MP对象的_val值。
    此时会产生问题,onResolved一定是函数吗?我们完成可能传一个非函数的值进去,臂如数字、字符串等等。
  • 如果是函数,那么执行onResolved同时将MP的值(_val)传递给它做参数,同时将onResolved返回的值作为返回的新MP对象的值。
  • 如果不是函数,直接将MP的值(_val)作为返回的新MP的值,新MP的状态延续旧MP的状态。
  1. 如果失败了
    同理,执行onRejected函数,并且将onRejected函数的返回值作为返回的MP对象的_val值。

为什么需要返回一个新的MP对象呢?为了支持链式调用,返回一个MP对象,我们就可以继续对返回值直接调用thencatch等方法。

状态onResolved返回值
成功是函数onResolved(val),新MP的状态为 fulfilled
不是函数原Promise值(val),状态不变,为 fulfilled
状态onRejected返回值
失败是函数onRejected(val),新MP的状态为 fulfilled
不是函数原Promise值(val),状态不变,为 rejected

如果onResolved或者onRejected执行出错了,系统抛出了异常,那么返回的MP的状态为fulfilled,值为抛出的异常。

then: createPropDes( function( onResolved, onRejected ) {
    const { _state, _val, isFunction } = this;
    var that = this;
    let res = new MP( function ( onNextResolved, onNextRejected ) {
      // 将成功和失败单独定义为两个函数
      let sucFn = function( _val ) {
        // resResult 成功状态处理函数的返回值
        let resResult;
        if ( isFunction( onResolved ) ) {	// onResolved 是函数
          resResult = onResolved( _val );	// 返回值
          if ( resResult instanceof MP ) {	
            // 返回值是 MP 类型,新返回的 MP 需要等待 resResult 的执行结果
              
            // 如果 resResult 最终状态为 fulfilled,那么执行 onNextResolved
            // 即 返回的 MP 的状态变为 fulfilled,值为 resResult 的值
              
            // 如果 resResult 最终状态为 rejected,那么执行 onNextRejected
            // 即 返回的 MP 的状态变为 rejected,值为 resResult 的值
            resResult.then( onNextResolved, onNextRejected );
          }
          else {
            onNextResolved( resResult );	// 返回值不是 MP 类型
          }
        }
        else {
          // 不是函数,直接将值传递给返回的 MP ,同时保留成功状态
          onNextResolved( _val );
        }
      }
      let failFn = function( _val ) {
        // rejResule 失败状态处理函数的返回值
        let rejResule;
        if ( isFunction( onRejected ) ) {	// onRejected 是函数
          rejResult = onRejected( _val );	// 返回值
          if ( rejResult instanceof MP ) {	// 返回值是 MP 类型
            rejResult.then( onNextResolved, onNextRejected );
          }
          else {
            onNextRejected( rejResult );	// 返回值不是 MP 类型
          }
        }
        else {
          // 不是函数,直接将值传递给返回的 MP ,同时保留失败状态
          onNextRejected( _val );
        }
      }
      switch ( _state ) {
        case state.Resolved:
          // 如果出现异常,抛出的异常会作为返回的 MP 的值,此时 返回的MP 状态为 rejected
          try{
            sucFn(); 
          }
          catch( err ) {
            onNextRejected( err );
          }
          break;
        case state.Rejected:
          try{
            failFn();
          }
          catch( err ) {
            onNextRejected( err );
          }
          break;
        // 以上是 then 执行的时候,MP对象已经确定状态的情况,那么如果还未确定状态呢?
        case state.Pending: 
          // ...
          break;
      }
    } );
    return res;
  } ),

对于状态为PendingMP对象,需要等MP执行完成之后,再确定返回的MP对象的值和状态。
我们可以在MP对象中设置两个队列,包含需要在MP确定状态之后去执行的操作。
一个队列包含成功状态执行的操作,另一个包含失败状态执行的操作。
此时,MP对象的成员属性都浮出水面了。

function MP( handle ) {
  this._state = state.Pending;
  this._val = undefined;
  this._resQue = [];	// 成功需处理的操作
  this._rejQue = [];	// 失败需处理的操作
  // ...
} 
MP.prototype = MpPrototype;

我们继续补全 case state.Pending:

 then: createPropDes( function( onResolved, onRejected ) {
    // 从 当前作为调用者的MP对象 获取 _resQue, _rejQue
    // 调用者在执行完成之后,会对_resQue, _rejQue队列里面保存的函数发起调用
    // 因为保存的是 onNextResolved, onNextRejected,
    // 所以调用的同时会引起新返回的 MP 对象的状态的改变
    const { _state, _val, _resQue, _rejQue, isFunction } = this;
    var that = this;
    let res = new MP( function ( onNextResolved, onNextRejected ) {
      let sucFn = function( _val ) {
      	// ...
      }
      let failFn = function( _val ) {
      	// ...
      }
      switch ( _state ) {
        case state.Resolved:
        	// ...
        case state.Rejected:
        	// ...
        case state.Pending: 
          that._resQue.push( sucFn );
          that._rejQue.push( failFn );
          break;
      }
    } );
    return res;
  } )
1.2.5.3 进一步完善resolve和reject函数

同时,更改resrej函数,使得它们在MP确定状态之后,调用队列里的函数。

res: createPropDes( function( val ) {
    let fn = () => {
      if ( !this.isPending() ) {  // 仅在Pending状态下可改变状态
        return;
      }
      let { _resQue, isFunction, state } = this;
      let that = this;

        that._state = state.Resolved;
        that._val = val;
        let mp;
        while ( _resQue.length ) {  // mp 是then投进来的函数
            mp = _resQue.shift();
            mp( val );
        }
    }
	// 为了除res之外的代码同步执行
    setTimeout(() => {
      fn();
    }, 0);
  } ),

Promise中,如果resolve函数传入的参数是一个Promise类型的对象,那么最终的Promise状态由传入的Promise对象决定,状态和传入的Promise对象保持同步。

传入作为参数的 Promise 对象的状态现有 Promise 的动作
fulfilled状态 = fulfilled,值 = 参数Promise的值
rejected状态 = rejected,值 = 参数Promise的值
pending等待参数Promise执行完成,再执行现有Promise的回调

但是,rej函数不会,对于rej会直接执行失败的回调,同时将Promise对象的值设置为传入作为参数的Promise对象。

// chrome
> var b = Promise.resolve(Promise.reject(123))
> undefined	(输出)
> b
> Promise {<rejected>: 123} (输出)
	[[Prototype]]: Promise
    [[PromiseState]]: "rejected"
    [[PromiseResult]]: 123

> var d = Promise.reject(Promise.resolve(234))
> undefined (输出)
> d
> Promise {<rejected>: Promise}	(输出)
	[[Prototype]]: Promise
	[[PromiseState]]: "rejected"
	[[PromiseResult]]: Promise	(展开该Promise)
    	[[Prototype]]: Promise	
        [[PromiseState]]: "fulfilled"
        [[PromiseResult]]: 234

可见res对于与传入的Promise保持同步,而res则是直接将传入的Promise作为值。

那么以此来完善现有MPres函数:

res: createPropDes( function( val ) {
    let fn = () => {
      if ( !this.isPending() ) {  // 仅在Pending状态下可改变状态
        return;
      }
      let { _resQue, _rejQue, isFunction, state } = this;
      let that = this;

      // 参数是Promise类型,状态为fulfilled,执行runSucFn
      let runSucFn = ( val ) => {	// 从fulfilled状态需要执行的回调事件队列中,去除并依次执行
        let mp;
        while ( _resQue.length ) {  // mp 是then投进来的函数
          mp = _resQue.shift();
          mp( val );
        }
      }
      // 参数是Promise类型,状态为fulfilled,执行runSucFn
      let runFailFn = ( err ) => {	// 从rejected状态需要执行的回调事件队列中,去除并依次执行
        let mp;
        while ( _rejQue.length ) {  // mp 是then投进来的函数
          mp = _rejQue.shift();
          mp( err );
        }
      }
      if ( val instanceof MP ) {	// 传入参数是MP类型
		// 给传入的MP添加回调
        val.then( val => {			// 传入MP fulfilled
          that._state = state.Resolved;	// that 指向当前 MP
          that._val = val;
          runSucFn( val );			// 将当前MP对象,成功状态的回调函数全部执行
        }, err => {					// 传入MP rejected
          that._state = state.Rejected;
          that._val = err;
          runFailFn( val );
        } )
      }
      else {						// 传入参数不是MP类型
        that._state = state.Resolved;
        that._val = val;
        runSucFn( val );			// 将当前MP对象,失败状态的回调函数全部执行
      }
    }
    setTimeout(() => {
      fn();
    }, 0);
  } ),

仿照第一版的res写出rej即可:

  rej: createPropDes( function( err ) {
    let fn = () => {
      if ( !this.isPending() ) {
        return;
      }
      let { _resQue, _rejQue, isFunction, state } = this;
      let that = this;
      let mp;
      while ( _rejQue.length ) {  // mp 是then投进来的函数
        mp = _rejQue.shift();
        mp( err );
      }
      this._state = state.Rejected;
      this._val = err;
    }
    setTimeout(() => {
      fn();
    }, 0);
  } ),

至此,最主要的res,rej,then实现完成。
小结一下:
对于resrej:

let a = new MP( (res, rej) => {
    res( b );
} )
bb状态
resisMP()b._state === fulfilleda._state = fulfilled
a._val = b._val
执行a成功回调
b._state === rejecteda._state = rejected
a._val = b._val
执行a失败回调
b._state === pendingb.then( () => {
a._state = fulfilled
a._val = b._val
}, () => {
a._state = rejected
a._val = b,_val
})
!isMP()a._state = fulfilled
a._val = b
reja._state = rejected
a._val = b
var onRes, onRej;
// onRes = function() {}
// onRej = function() {}
let b = a.then( onRes, onRej );
then._stateisFunction( onRes )let res = onRes( a._val )
res instanceof MP
fulfilledfalseb._state = fulfilled
b._val = a._val
truetrueb._state = res._state
b._val = res._val
(具体细节,在then的实现部分有)
falseb._state = fulfilled
b._val = res
rejectedfalseb._state = rejected
b._val = a._val
truetrueb._state = res._state
b._val = res._val
(具体细节,在then的实现部分有)
falseb._state = rejected
b._val = res
pendingb._state = pending
(具体在then,pending部分实现)
1.2.5.4 实现catch
catch: createPropDes( function( onRejected ) {
    return this.then( undefined, onRejected );
  } ),
1.2.5.5 实现静态方法resolve、reject和all
  resolve: createPropDes( function( val ) { 
    if ( val instanceof MP ) return val;
    return new Promise( function( res, rej ) {
      res( val );
    } );
  } ),
  reject: createPropDes( function( err ) {
    if ( err instanceof MP ) return err;
    return new Promise( function( res, rej ) {
      rej( err );
    } )
  } ),
   all: createPropDes( function( MPList ) {
	  return new Promise( function( res, rej ) {
	    let result = [];
	    let count = 0;
	    for ( let [ index, item ] of MPList ) {
	      item.then( val => {
	        result[ index ] = val;
	        count++;
	        if ( count === MPList.length ) {
	          res( result );
	        }
	      }, err => {
	        rej( err );
	      } );
	    }
	  } )
  	} ),
1.2.5.6 实现静态方法race和finally
race: createPropDes( function( MPList ) {
    return new Promise( function ( res, rej ) { 
      for ( let [ index, item ] of MPList ) {
        item.then( val => {
          res( val );	// 只有第一个res或者rej有效
        }, err => {
          rej( err );
        } )
      }
     } )
} ),
finally: createPropDes( function( mp ) {
  return this.then( 
    val => MP.resolve( mp() ),
    err => MP.reject( mp() )
   );
} ),
1.2.5.7 用到的其他辅助函数
 // 辅助的判断函数
  isFunction: createPropDes( function( fn ) {
	// 来自jQuery,nodeType兼容那种很过去的浏览器
    return typeof fn === 'function' && typeof fn.nodeType != 'number';	
  } ),
  isResolved: createPropDes( function() {
    return this._state === state.isResolved;
  } ),
  isRejected: createPropDes( function() {
    return this._state === state.Rejected;
  } ),
  isPending: createPropDes( function() {
    return this._state === state.Pending;
  } )
1.2.6 实现函数MP
function MP( handle ) {
  this._state = state.Pending;
  this._val = undefined;
  this._resQue = [];
  this._rejQue = [];

  if ( !this.isFunction( handle ) ) {
    throw new Error("Error: 只接收函数");
  }
  else {
    handle( this.res.bind(this), this.rej.bind(this) );
  }
}

handle调用的过程中,resrej的调用者为global,但是设置global_state显然是不对的,resrejthis必须始终指向MP对象,所以需要使用bind方法。

1.2.7 整体代码
// 原型
var MpPrototype = {};
// 状态
const state = {};
// 属性描述符对象
function createPropDes( value, writable = false, enumerable = true, configurable = false ) {
  return {
    value:        value,
    writable:     writable,
    enumerable:   enumerable,
    configurable: configurable
  }
}
Object.defineProperties( state, {
  Pending:  createPropDes( 'Pending' ),
  Resolved: createPropDes( 'Resolved' ),
  Rejected: createPropDes( 'Rejected' )
} )
Object.defineProperties( MpPrototype, {
  state: createPropDes( state ),
  res: createPropDes( function( val ) {
    // console.log('res', this)
    let fn = () => {
      // console.log('fn', this)
      if ( !this.isPending() ) {  // 仅在Pending状态下可改变状态
        return;
      }
      let { _resQue, _rejQue, isFunction, state } = this;
      let that = this;

      let runSucFn = ( val ) => {
        let mp;
        while ( _resQue.length ) {  // mp 是then投进来的函数
          mp = _resQue.shift();
          mp( val );
        }
      }
      let runFailFn = ( err ) => {
        let mp;
        while ( _rejQue.length ) {  // mp 是then投进来的函数
          mp = _rejQue.shift();
          mp( err );
        }
      }
      if ( val instanceof MP ) {
        val.then( val => {
          that._state = state.Resolved;
          that._val = val;
          runSucFn( val );
        }, err => {
          that._state = state.Rejected;
          that._val = err;
          runFailFn( val );
        } )
      }
      else {
        that._state = state.Resolved;
        that._val = val;
        runSucFn( val );
      }
    }
    setTimeout(() => {
      fn();
    }, 0);
  } ),
  rej: createPropDes( function( err ) {
    let fn = () => {
      if ( !this.isPending() ) {
        return;
      }
      let { _resQue, _rejQue, isFunction, state } = this;
      let that = this;
      let mp;
      while ( _rejQue.length ) {  // mp 是then投进来的函数
        mp = _rejQue.shift();
        mp( err );
      }
      this._state = state.Rejected;
      this._val = err;
    }
    setTimeout(() => {
      fn();
    }, 0);
  } ),
  then: createPropDes( function( onResolved, onRejected ) {
    const { _state, _val, _resQue, _rejQue, isFunction } = this;
    var that = this;
    let res = new MP( function ( onNextResolved, onNextRejected ) {
      let sucFn = function( _val ) {
        let resResult;
        if ( isFunction( onResolved ) ) {
          console.log('_val', _val)
          resResult = onResolved( _val );
          if ( resResult instanceof MP ) {
            resResult.then( onNextResolved, onNextRejected );
          }
          else {
            onNextResolved( resResult );
          }
        }
        else {
          onNextResolved( _val );
        }
      }
      let failFn = function( _val ) {
        let rejResule;
        if ( isFunction( onRejected ) ) {
          rejResult = onRejected( _val );
          if ( rejResult instanceof MP ) {
            rejResult.then( onNextResolved, onNextRejected );
          }
          else {
            onNextRejected( rejResult );
          }
        }
        else {
          onNextRejected( _val );
        }
      }
      switch ( _state ) {
        case state.Resolved:
          try{
            sucFn(); 
          }
          catch( err ) {
            onNextRejected( err );
          }
          break;
        case state.Rejected:
          try{
            failFn();
          }
          catch( err ) {
            onNextRejected( err );
          }
          break;
        case state.Pending: 
          that._resQue.push( sucFn );
          that._rejQue.push( failFn );
          break;
      }
    } );
    return res;
  } ),
  catch: createPropDes( function( onRejected ) {
    return this.then( undefined, onRejected );
  } ),

  // 静态方法
  resolve: createPropDes( function( val ) { 
    if ( val instanceof MP ) return val;
    return new Promise( function( res, rej ) {
      res( val );
    } );
  } ),
  reject: createPropDes( function( err ) {
    if ( err instanceof MP ) return err;
    return new Promise( function( res, rej ) {
      rej( err );
    } )
  } ),
  all: createPropDes( function( MPList ) {
  return new Promise( function( res, rej ) {
    let result = [];
    let count = 0;
    for ( let [ index, item ] of MPList ) {
      item.then( val => {
        result[ index ] = val;
        count++;
        if ( count === MPList.length ) {
          res( result );
        }
      }, err => {
        rej( err );
      } );
    }
  } )
  } ),
  race: createPropDes( function( MPList ) {
    return new Promise( function ( res, rej ) { 
      for ( let [ index, item ] of MPList ) {
        item.then( val => {
          res( val );
        }, err => {
          rej( err );
        } )
      }
     } )
  } ),
  finally: createPropDes( function( mp ) {
    return this.then( 
      val => MP.resolve( mp() ),
      err => MP.reject( mp() )
     );
  } ),

  // 辅助的判断函数
  isFunction: createPropDes( function( fn ) {
    return typeof fn === 'function' && typeof fn.nodeType != 'number';
  } ),
  isResolved: createPropDes( function() {
    return this._state === state.isResolved;
  } ),
  isRejected: createPropDes( function() {
    return this._state === state.Rejected;
  } ),
  isPending: createPropDes( function() {
    return this._state === state.Pending;
  } )

});

function MP( handle ) {
  this._state = state.Pending;
  this._val = undefined;
  this._resQue = [];
  this._rejQue = [];

  if ( !this.isFunction( handle ) ) {
    throw new Error("Error: 只接收函数");
  }
  else {
    handle( this.res.bind(this), this.rej.bind(this) );
  }
} 

MP.prototype = MpPrototype;

let a = new MP( ( res, rej ) => {
  rej(1)
} )
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值