参考链接
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
那么会终止函数,后面的内容不会执行。(使用
nodejs
12版本,提示TypeError: Promise.any is not a function
,mdn
显示nodejs
16版本以后支持,更新了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
捕捉到,需要Promise
的catch
函数。
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
对象的构造函数。
-
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
对象。
结束模拟,实具体实现一下res
和rej
函数:
// 原型
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引用的是定义箭头函数的上下文。
我们可以先快进到后续的步骤,对于res
和rej
函数,最后的调用情况应该形如:
function MP() {
this.res(...)
}
我们需要让this
始终指向MP
(MyPromise)对象。
首先,在MP
函数内使用this.res
,res
是一个标准函数,《高程(第四版)》第300页:
在标准函数中,this引用的是把函数当成方法调用的上下文对象。
简单来说,标准函数中this
指向调用者,(如果没有直接的调用者,this
指向全局上下文,浏览器中指向window
,nodejs
全局中输出this
结果为{}
,函数中输出this
结果为global
对象;在严格模式下this
指向undefined
),箭头函数中this
始终指向定义时候的函数(的上下文)。
那么res
内部this
的指向为MP
对象。
在此时,定义了fn
函数类型变量,由于fn
是箭头函数,fn
的this
指向定义时候的上下文,所以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
对象从resolve
和reject
函数获得的值,最终传递给了then
函数的两个回调函数。
所以,可以先进行简单模拟:
function MP() {
this.then = function( onResolved, onRejected ){
if ( 成功 ) {
onResolved( this._val ); // MP 对象的值传递给onResolved函数作为参数
}
else if ( 失败 ) {
onRejected( this._val ); // MP 对象的值传递给onRejected函数作为参数
}
else if ( 还没出结果 ) {
// ...
}
}
}
- 如果成功了
此时需要执行onResolved
函数,并且将onResolved
函数的返回值作为返回的MP
对象的_val
值。
此时会产生问题,onResolved
一定是函数吗?我们完成可能传一个非函数的值进去,臂如数字、字符串等等。
- 如果是函数,那么执行
onResolved
同时将MP
的值(_val)传递给它做参数,同时将onResolved
返回的值作为返回的新MP
对象的值。 - 如果不是函数,直接将
MP
的值(_val)作为返回的新MP
的值,新MP
的状态延续旧MP
的状态。
- 如果失败了
同理,执行onRejected
函数,并且将onRejected
函数的返回值作为返回的MP
对象的_val
值。
为什么需要返回一个新的MP
对象呢?为了支持链式调用,返回一个MP
对象,我们就可以继续对返回值直接调用then
、catch
等方法。
状态 | 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;
} ),
对于状态为Pending
的MP
对象,需要等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函数
同时,更改res
和rej
函数,使得它们在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
作为值。
那么以此来完善现有MP
的res
函数:
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
实现完成。
小结一下:
对于res
和rej
:
let a = new MP( (res, rej) => {
res( b );
} )
b | b状态 | ||
---|---|---|---|
res | isMP() | b._state === fulfilled | a._state = fulfilled a._val = b._val 执行a成功回调 |
b._state === rejected | a._state = rejected a._val = b._val 执行a失败回调 | ||
b._state === pending | b.then( () => { a._state = fulfilled a._val = b._val }, () => { a._state = rejected a._val = b,_val }) | ||
!isMP() | a._state = fulfilled a._val = b | ||
rej | a._state = rejected a._val = b |
var onRes, onRej;
// onRes = function() {}
// onRej = function() {}
let b = a.then( onRes, onRej );
then._state | isFunction( onRes ) | let res = onRes( a._val ) res instanceof MP | |
---|---|---|---|
fulfilled | false | b._state = fulfilled b._val = a._val | |
true | true | b._state = res._state b._val = res._val (具体细节,在then的实现部分有) | |
false | b._state = fulfilled b._val = res | ||
rejected | false | b._state = rejected b._val = a._val | |
true | true | b._state = res._state b._val = res._val (具体细节,在then的实现部分有) | |
false | b._state = rejected b._val = res | ||
pending | b._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
调用的过程中,res
和rej
的调用者为global
,但是设置global
的_state
显然是不对的,res
和rej
的this
必须始终指向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)
} )