Promise 有哪些方法?

  • Promise.prototype.then
    then() 方法需要两个参数,第一个参数作为处理 fulfilled 状态的回调函数,回调函数有一个入参即 fufilled 状态的结果,而第二个参数则作为处理 rejected 状态的回调函数,回调函数有一个入参即 rejected 的原因。返回一个新的 Promise。
  • Promise.prototype.catch
    catch() 方法返回一个新的 Promise,并且处理 rejected 的情况。它的行为与调用 Promise.prototype.then(undefined, onRejected) 相同
  • Promise.prototype.finally
    finally() 方法返回一个新的 Promise。在 promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数。
  • Promise.resolve()
    Promise.resolve() 方法返回一个以给定值解析后的 Promise 对象。如果这个值是一个 promise,那么将返回这个 promise;如果这个值是 thenable(即带有 “then” 方法),返回的 promise 会“跟随”这个 thenable 的对象,采用它的最终状态;否则返回的 promise 将以此值完成。此函数将类 promise 对象的多层嵌套展平。
  • Promise.reject()
    Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象。
  • Promise.all()
    Promise.all() 方法接收一个 promise 的 iterable 类型(Array Map Set)的输入,并且只返回一个Promise 实例。当输入的所有 promise 均 fulfilled 后,执行返回的 Promise 实例的 resolve 方法,只要有任何一个输入的 promise reject,执行返回的 Promise 实例的 reject 方法,reject 的 reason 是第一个 reject 的 promise 的 reason
  • Promise.allSettled()
    Promise.allSettled() 方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果
  • Promise.any()
    Promise.any() 方法接收一个由 Promise 所组成的可迭代对象,该方法会返回一个新的 promise,一旦可迭代对象内的任意一个 promise 变成了 fulfilled 状态,那么由该方法所返回的 promise 就会变成 fulfilled 状态,并且它的返回值就是可迭代对象内的首先 fulfilled 的 promise 的返回值。如果可迭代对象内的 promise 最终都没有 fulfilled(即所有 promise 都是 rejected),那么该方法所返回的 promise 就会变成 rejected 状态,并且它的拒因会是一个 AggregateError 实例,这是 Error 的子类,用于把单一的错误集合在一起
  • Promise.race()
    Promise.race() 方法接收一个由 Promise 所组成的可迭代对象,返回一个新的 Promise。一旦迭代器中的某个 promise fullfiled 或 rejected,返回的 promise 就会 fullfiled 或 rejected,值和原因均与第一个返回的 promise 相同。

以下实现一个遵循 PromiseA+ 规范的 Promise 。

实现基础框架 new Promise((resolve, reject) =>{})

new Promise() 时接收一个 executor 函数作为参数,该函数会立即执行,函数中有两个参数,它们也是函数,分别是 resolve 和 reject ,函数同步执行一定要放在 try…catch 中,否则无法进行错误捕获。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
function MyPromise(executor) {
function resolve(value) {}

function reject(reason) {}

try {
executor(resolve, reject);
} catch (reason) {
reject(reason);
}
}

module.exports = MyPromise;

resolve() 接收 Promise 成功值 value , reject 接收 Promise 失败原因 reason 。

test.js
1
2
3
4
5
const MyPromise = require('./MyPromise.js');

let promise = new MyPromise((resolve, reject) => {
resolve(123);
});

添加状态机 pending fulfilled rejected

Promise 是一个状态机的机制,初始状态为 pending,成功状态为 fulfilled,失败状态为 rejected。只能从 pending -> fulfilled,或者从 pending -> rejected,并且状态一旦转变,就永远不会再变了。
所以,我们需要为 Promise 添加一个状态流转的机制。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function MyPromise(executor) {
let self = this;
self.state = PENDING;


function resolve(value) {
if (self.state === PENDING) {
self.state = FULFILLED;
}
}

function reject(reason) {
if (self.state === PENDING) {
self.state = REJECTED;
}
}

try {
executor(resolve, reject);
} catch (reason) {
reject(reason);
}
}

module.exports = MyPromise;

添加 then 方法

Promise 拥有一个 then 方法,接收两个函数 onFulfilled 和 onRejected,分别作为 Promise 成功和失败的回调。所以,在 then 方法中我们需要对状态 state 进行判断,如果是 fulfilled ,则执行 onFulfilled(value) 方法,如果是 rejected ,则执行 onRejected(reason) 方法。

由于成功值 value 和失败原因 reason 是由用户在 executor 中通过 resolve(value) 和 reject(reason) 传入的,所以我们需要有一个全局的 value 和 reason 供后续方法获取。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function MyPromise(executor) {
let self = this;

self.state = PENDING;
self.value = null;
self.reason = null;

function resolve(value) {
if (self.state === PENDING) {
self.state = FULFILLED;
self.value = value;
}
}

function reject(reason) {
if (self.state === PENDING) {
self.state = REJECTED;
self.reason = reason;
}
}

try {
executor(resolve, reject);
} catch (reason) {
reject(reason);
}
}

MyPromise.prototype.then = function(onFuifilled, onRejected) {
let self = this;

if (self.state === FULFILLED) {
onFuifilled(self.value);
}

if (self.state === REJECTED) {
onRejected(self.reason);
}
};

module.exports = MyPromise;
test.js
1
2
3
4
5
6
7
8
9
10
11
let MyPromise = require('./MyPromise.js');

let promise = new MyPromise(function(resolve, reject) {
resolve(123);
});

promise.then(function(value) {
console.log('value', value);
}, function(reason) {
console.log('reason', reason);
});

实现异步调用 resolve

当前的实现同步调用 resolve() 没有问题,但如果是异步调用,比如放到 setTimeout 中,因为目前的代码在调用 then() 方法时, state 仍是 pending 状态,当 timer 到时候调用 resolve() 把 state 修改为 fulfilled 状态,但是 onFulfilled() 函数已经没有时机调用了。

所以我们需要添加回调堆栈,当处于 pending 状态时,将 onFulfilled() 函数和 onRejected() 函数放到相应的堆栈中去。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function MyPromise(executor) {
let self = this;

self.state = PENDING;
self.value = null;
self.reason = null;
self.onFulfilledCallbacks = [];
self.onRejectedCallbacks = [];

function resolve(value) {
if (self.state === PENDING) {
self.state = FULFILLED;
self.value = value;

self.onFulfilledCallbacks.forEach(function(fulfilledCallback) {
fulfilledCallback();
});
}
}

function reject(reason) {
if (self.state === PENDING) {
self.state = REJECTED;
self.reason = reason;

self.onRejectedCallbacks.forEach(function(rejectedCallback) {
rejectedCallback();
});
}
}

try {
executor(resolve, reject);
} catch (reason) {
reject(reason);
}
}

MyPromise.prototype.then = function(onFuifilled, onRejected) {
let self = this;

if (self.state === PENDING) {
self.onFulfilledCallbacks.push(() => {
onFuifilled(self.value);
});
self.onRejectedCallbacks.push(() => {
onRejected(self.reason);
});
}

if (self.state === FULFILLED) {
onFuifilled(self.value);
}

if (self.state === REJECTED) {
onRejected(self.reason);
}
};

module.exports = MyPromise;

我们添加了两个回调函数数组 onFulfilledCallbacks 和 onRejectedCallbacks ,用来存储 then() 方法中传入的成功和失败回调。然后,当用户调用 resolve() 或 reject() 的时候,修改 state 状态,并从相应的回调数组中依次取出回调函数执行。

同时,通过这种方式我们也实现了可以注册多个 then() 函数,并且在成功或者失败时按照注册顺序依次执行。

test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let MyPromise = require('./MyPromise.js');

let promise = new MyPromise(function(resolve, reject) {
setTimeout(function() {
resolve(123);
}, 1000);
});

promise.then(function(value) {
console.log('value1', value);
}, function(reason) {
console.log('reason1', reason);
});

promise.then(function(value) {
console.log('value2', value);
}, function(reason) {
console.log('reason2', reason);
});

链式调用 then 返回的仍是 Promise

读过 Promise A+ 规范的同学肯定知道,then() 方法返回的仍是一个 Promise ,并且返回 Promise 的 resolve 的值是上一个 Promise 的 onFulfilled() 函数或 onRejected() 函数的返回值。如果在上一个 Promise 的 then() 方法回调函数的执行过程中发生了错误,那么会将其捕获到,并作为返回的 Promise 的 onRejected 函数的参数传入。

接下来我们就去实现 then() 方法依然返回一个 Promise 。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
MyPromise.prototype.then = function(onFuifilled, onRejected) {
let self = this;
let promise2 = null;

promise2 = new MyPromise((resolve, reject) => {
if (self.state === PENDING) {
self.onFulfilledCallbacks.push(() => {
try {
let x = onFuifilled(self.value);
self.resolvePromise(promise2, x, resolve, reject);
} catch(reason) {
reject(reason);
}
});
self.onRejectedCallbacks.push(() => {
try {
let x = onRejected(self.reason);
self.resolvePromise(promise2, x, resolve, reject);
} catch(reason) {
reject(reason);
}
});
}

if (self.state === FULFILLED) {
try {
let x = onFuifilled(self.value);
self.resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
}

if (self.state === REJECTED) {
try {
let x = onRejected(self.reason);
self.resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
}
});

return promise2;
};

可以看到,我们新增了一个 promise2 作为 then() 方法的返回值。通过 let x = onFuifilled(self.value) 或者 let x = onRejected(self.reason) 拿到 then() 方法回调函数的返回值,然后调用 self.resolvePromise(promise2, x, resolve, reject),将新增的 promise2、x、promise2 的 resolve 和 reject 传入到 resolvePromise() 中。

下面我们重点看一下 resolvePromise() 方法。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
MyPromise.prototype.resolvePromise = function(promise2, x, resolve, reject) {
let self = this;
let called = false; // called 防止多次调用

if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<MyPromise>'));
}

// Promises/A+ 希望自身能兼容其他规范下的 promise 对象,判断依据为该对象是否可 thenable
if (x !== null && (Object.prototype.toString.call(x) === '[object Object]' || Object.prototype.toString.call(x) === '[object Function]')) {
// x是对象或者函数
try {
let then = x.then;

if (typeof then === 'function') {
then.call(x, (y) => {
// 别人的Promise的then方法可能设置了getter等,使用called防止多次调用then方法
if (called) return ;
called = true;
// 成功值y有可能还是promise或者是具有then方法等,再次resolvePromise,直到成功值为基本类型或者非thenable
self.resolvePromise(promise2, y, resolve, reject);
}, (reason) => {
if (called) return ;
called = true;
reject(reason);
});
} else {
if (called) return ;
called = true;
resolve(x);
}
} catch (reason) {
if (called) return ;
called = true;
reject(reason);
}
} else {
// x是普通值,直接resolve
resolve(x);
}
};

resolvePromise() 是用来解析 then() 回调函数中返回的仍是一个 Promise ,这个 Promise 有可能是我们自己的,有可能是别的库实现的,也有可能是一个具有 then() 方法的对象,所以这里靠 resolvePromise() 来实现统一处理。

test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let MyPromise = require('./MyPromise.js');

let promise = new MyPromise(function(resolve, reject) {
setTimeout(function() {
resolve(123);
}, 1000);
});

promise.then((value) => {
console.log('value1', value);
return new MyPromise((resolve, reject) => {
resolve(456);
}).then((value) => {
return new MyPromise((resolve, reject) => {
resolve(789);
})
});
}, (reason) => {
console.log('reason1', reason);
}).then((value) => {
console.log('value2', value);
}, (reason) => {
console.log('reason2', reason);
});

让 then 方法的回调函数总是异步调用

Promise 属于 microTask,我们可以通过 process.nextTick() 来将 then 方法的回调函数改为异步

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
MyPromise.prototype.then = function(onFuifilled, onRejected) {
let self = this;
let promise2 = null;

promise2 = new MyPromise((resolve, reject) => {
if (self.state === PENDING) {
self.onFulfilledCallbacks.push(() => {
process.nextTick(()=>{
try {
let x = onFuifilled(self.value);
self.resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
});
});
self.onRejectedCallbacks.push(() => {
process.nextTick(()=>{
try {
let x = onRejected(self.reason);
self.resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
});
});
}

if (self.state === FULFILLED) {
process.nextTick(()=>{
try {
let x = onFuifilled(self.value);
self.resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
});
}

if (self.state === REJECTED) {
process.nextTick(()=>{
try {
let x = onRejected(self.reason);
self.resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
});
}
});

return promise2;
};
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let MyPromise = require('./MyPromise.js');

console.log('start');

let promise = new MyPromise((resolve, reject) => {
console.log('step-');
setTimeout(() => {
resolve(123);
}, 1000);
});

promise.then((value) => {
console.log('step--');
console.log('value1', value);
});

console.log('end');
/*
打印结果:
start
step-
end
step--
value1 123
*/

经过以上步骤,一个最基本的 Promise 就已经实现完了,下面我们会实现一些不在 PromiseA+ 规范的扩展方法。

实现 catch 方法

then() 方法的 onFulfilled 和 onRejected 回调函数都不是必传项,如果不传,那么我们就无法接收 reject(reason) 中的错误,这时我们可以通过链式调用 catch() 方法用来接收错误。

不仅如此,catch() 可以作为 Promise 链式调用的最后一步,前面 Promise 发生的错误会冒泡到最后一个 catch() 中,从而捕获异常。

MyPromise.js
1
2
3
4
5
6
7
8
9
MyPromise.prototype.then = function(onFuifilled, onRejected) {
onFuifilled = typeof onFuifilled === 'function' ? onFuifilled : value => {return value;};
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason};
// ...
};

MyPromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};

可以看到,onRejected 的默认值是把错误 reason 通过 throw 抛出去。由于我们对于同步代码的执行都是在 try…catch 中的,所以如果 Promise 发生了错误,如果没传 onRejected ,默认的函数会把错误 reason 抛出,然后会被 promise2 捕捉到,作为 reject(reason) 决议。

所以,我们在写 Promise 的链式调用的时候,在 then() 中可以不传 onRejected 回调,只需要在链式调用的最末尾加一个 catch() 就可以了,这样在该链条中的 Promise 发生的错误都会被最后的 catch 捕获到。

实现 finally 方法

finally 是某些库对 Promise 实现的一个扩展方法,无论是 resolve 还是 reject ,都会走 finally 方法。

MyPromise.js
1
2
3
4
5
6
7
8
9
MyPromise.prototype.finally = function(fn) {
return this.then(value => {
fn();
return value;
}, reason => {
fn();
throw reason;
});
};

实现 done 方法

done 方法作为 Promise 链式调用的最后一步,用来向全局抛出没有被 Promise 内部捕获的错误,并且不再返回一个 Promise 。一般用来结束一个 Promise 链。

MyPromise.js
1
2
3
4
5
MyPromise.prototype.done = function() {
this.catch(reason => {
throw reason;
});
};

实现 Promise.all 方法

Promise.all() 接收一个包含多个 Promise 的数组,当所有 Promise 均为 fulfilled 状态时,返回一个结果数组,数组中结果的顺序和传入的 Promise 顺序一一对应。如果有一个 Promise 为 rejected 状态,则整个 Promise.all 为 rejected 。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MyPromise.all = function(promiseArr) {
return new MyPromise((resolve, reject) => {
let result = [];
let fulfilledPromise = 0;

promiseArr.forEach((promise, index) => {
promise.then((value) => {
result[index] = value;
if (++fulfilledPromise === promiseArr.length) {
resolve(result);
}
}, reject);
});
});
};
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
let MyPromise = require('./MyPromise.js');

let promise1 = new MyPromise((resolve, reject) => {
console.log('aaaa');
setTimeout(() => {
resolve(1111);
console.log(1111);
}, 1000);
});

let promise2 = new MyPromise((resolve, reject) => {
console.log('bbbb');
setTimeout(() => {
reject(2222);
console.log(2222);
}, 2000);
});

let promise3 = new MyPromise((resolve, reject) => {
console.log('cccc');
setTimeout(() => {
resolve(3333);
console.log(3333);
}, 3000);
});

Promise.all([promise1, promise2, promise3]).then((value) => {
console.log('all value', value);
}, (reason) => {
console.log('all reason', reason);
})
/*
打印结果:
aaaa
bbbb
cccc
1111
2222
all reason 2222
3333
*/

实现 Promise.race 方法

Promise.race() 接收一个包含多个 Promise 的数组,当有一个 Promise 为 fulfilled 状态时,则整个 Promise.race 为 onfulfilled ,并执行 onFulfilled 回调函数。如果有一个 Promise 为 rejected 状态,则整个 Promise.race 为rejected。

MyPromise.js
1
2
3
4
5
6
7
8
9
MyPromise.race = function(promiseArr) {
return new MyPromise((resolve, reject) => {
promiseArr.forEach(promise => {
promise.then((value) => {
resolve(value);
}, reject);
});
});
};
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
let MyPromise = require('./MyPromise.js');

let promise1 = new MyPromise((resolve, reject) => {
console.log('aaaa');
setTimeout(() => {
resolve(1111);
console.log(1111);
}, 1000);
});

let promise2 = new MyPromise((resolve, reject) => {
console.log('bbbb');
setTimeout(() => {
reject(2222);
console.log(2222);
}, 2000);
});

let promise3 = new MyPromise((resolve, reject) => {
console.log('cccc');
setTimeout(() => {
resolve(3333);
console.log(3333);
}, 3000);
});

Promise.race([promise1, promise2, promise3]).then((value) => {
console.log('all value', value);
}, (reason) => {
console.log('all reason', reason);
});
/*
打印结果:
aaaa
bbbb
cccc
1111
all reason 1111
2222
3333
*/

实现 Promise.resolve 方法

Promise.resolve 用来生成一个 fulfilled 完成态的 Promise ,一般放在整个 Promise 链的开头,用来开始一个 Promise 链。

MyPromise.js
1
2
3
4
5
6
7
8
9
MyPromise.resolve = function(value) {
let promise;

promise = new MyPromise((resolve, reject) => {
this.prototype.resolvePromise(promise, value, resolve, reject);
});

return promise;
};
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let MyPromise = require('./MyPromise.js');

MyPromise.resolve(1111).then((value) => {
console.log('value1', value);
return new MyPromise((resolve, reject) => {
resolve(2222);
})
}).then((value) => {
console.log('value2', value);
});
/*
打印结果:
value1 1111
value2 2222
*/

实现 Promise.reject 方法

Promise.reject 用来生成一个 rejected 失败态的 Promise 。

MyPromise.js
1
2
3
4
5
MyPromise.reject = function(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
};
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let MyPromise = require('./MyPromise.js');

MyPromise.reject(1111).then((value) => {
console.log('value1', value);
return new MyPromise((resolve, reject) => {
resolve(2222);
})
}).then((value) => {
console.log('value2', value);
}).catch(reason => {
console.log('reason', reason);
});
/*
打印结果:
reason 1111
*/

实现 Promise.deferred 方法

MyPromise.js
1
2
3
4
5
6
7
8
MyPromise.deferred = function() {
let dfd = {};
dfd.promise = new MyPromise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
};

这样,你就可以在外部通过调用 dfd.resolve() 和 dfd.reject() 来决议该 Promise。

实现 Promise.allSettled 方法

Promise.allSettled 接收一个包含多个 Promise 的数组(实际只需要实现 Iterable ),当所有的 Promise 均不为 pending 状态时,返回一个结果数组,数组中结果的顺序和传入的 Promise 顺序一一对应,每个结果中的 status 字段表示结果的状态,value 或 reason 字段表示成功的结果或失败的原因。

MyPromise.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
MyPromise.allSettled = function (promiseArr) {
return new MyPromise((resolve, _reject) => {
let result = [];
let settledPromise = 0;
function addToResult(idx, value) {
result[idx] = value;
settledPromise++;
if (settledPromise === promiseArr.length) {
resolve(result);
}
}
promiseArr.forEach((promise, idx) => {
if (promise instanceof MyPromise) {
promise.then((value) => {
addToResult(idx, {
status: FULFILLED,
value
});
}, (reason) => {
addToResult(idx, {
status: REJECTED,
reason
});
});
return;
}
addToResult(idx, {
status: FULFILLED,
value: promise
});
});
});
}

实现中使用了 promise instanceof MyPromise 来判断是否可以使用 then 方法,更准确的方法应该判断是否实现了 thenable 接口。

实现 Promise.any 方法

Promise.any 接收一个包含多个 Promise 的数组(实际只需要实现 Iterable ),当有一个 Promise 为 fulfilled 状态时,则整个 Promise.any 为 onfulfilled,并执行 onFulfilled 回调函数。如果所有的 Promise 均 rejected 了,则整个 Promise.andy 为 rejected.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MyPromise.any = function(promiseArr) {
return new MyPromise((resolve, reject) => {
let reasons = [];
let rejectedPromise = 0;
promiseArr.forEach((promise, idx) => {
if (promise instanceof MyPromise) {
promise.then(resolve, (reason) => {
reasons[idx] = reason;
rejectedPromise++;
if (rejectedPromise === promiseArr.length) {
reject(new AggregateError(reasons, 'All Promises rejected'));
}
});
return;
}
resolve(promise);
});
});
}