Promise 学习系列:中篇

前言

有了上一篇的内容,相信读者你已经对 Promise 的主体实现已经有了一定掌握。本文将是这个系列的中篇内容,本篇将对 Promise 规范里的对象方法和静态方法进行内容,最后在下篇针对实际面试和使用场景进行讲解。

1、实例方法

then、catch 以及 finally 方法都是 Promise.prototype 里的方法,都属于实例方法。上篇中我们以及实现了前两个,接下来我们给出 finally 方法的实现。

1.1、finally 实现

finally 是 Promise 实例的一个方法,在上篇内容中有提到,我们现在先补上这部分内容。首先,我们来看一下 finally 。

  • finally 会在 onfulfilled/onrejected 回调执行完之后被执行到
  • finally 会返回一个新的 promise 对象,并且这个对象的状态为 fulfilled,fulfilledValue 为 undefined

那么,finally 代码实现为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
*
* @param {*} onfinally
* @returns
*/
MyPromise.prototype.finally = function(onfinally){
return new MyPromise((resolve, reject) => {
this._handle({
type: TYPES.FINALLY,
resolve,
reject,
onfinally
})
})
}

2、静态方法

Promise 的静态方法有很多,但是基本上按传入参数可以分两类,Promise 对象数组(或 iterable 类型,Array,Map,Set都属于ES6的 iterable 类型,下文中我们简化为数组类型的情形)和其他。我们先来看看归纳在 “其他” 里的方法。

2.1、resolve、reject 实现

这里的 resolve、reject 有别于上篇中 MyPromise 中的内部方法,这两个方法都接受一个参数,并得到一个 promise 对象,其 fulfilledValue/rejectedReason 就是传入参数。比较简单,我们直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
MyPromise.resolve = function(rs) {
const pro = new MyPromise(resolve => {
resolve(rs)
})
return pro
}
MyPromise.reject = function(err) {
const pro = new MyPromise((resolve, reject) => {
reject(err)
})
return pro
}

2.2、race 实现

传入一个 Promise 类型数组,返回一个 Promise 对象。
其中任意一个 promise 对象达到终态,则进入 onfulfilled 或 onrejected 函数。
如果入参空数组,则 pending,非数组类型入参会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MyPromise.race = function(array){
if(!Array.isArray(array)) throw new Error('array not Array')
return new MyPromise((resolve, reject)=>{
const len = array.length
for (let i = 0; i < len; i++) {
const p = array[i];
p.then(res=>{
resolve(res)
})
.catch(err=>{
reject(err)
})
}
})
}

2.3、all 实现

传入一个 Promise 类型数组,返回一个 Promise 对象。
当所有 promise 达到 fullfilled 或 任意一个 promise 达到 rejected,则结束。
如果入参空数组,则返回一个 fullfilled 的promise,非数组类型入参会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MyPromise.all = function(array) {
if(!Array.isArray(array)) throw new Error('array not Array')
return new MyPromise((resolve, reject)=>{
const ans = []
let count = 0
const len = array.length
if(len === 0) resolve(ans)
//
for (let i = 0; i < len; i++) {
const p = array[i];
p.then(res=>{
ans[i] = res
count++
if(count === len)
resolve(ans)
})
.catch(err=>{
reject(err)
})
}
})
}

2.4、allSettled 实现

传入一个 Promise 类型数组,返回一个 Promise 对象。
当所有 promise 达到 fullfilled 或 rejected,则结束。
如果入参空数组,则返回一个 fullfilled 的promise,非数组类型入参会报错

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
MyPromise.allSettled = function(array) {
if(!Array.isArray(array)) throw new Error('array not Array')
return new MyPromise((resolve, reject)=>{
const ans = []
let count = 0
const len = array.length
if(len === 0) resolve(ans)
//
for (let i = 0; i < len; i++) {
const p = array[i];
p.then(res=>{
ans[i] = {
status: PRO_STATUS.FULFILLED,
value: res
}
count++
if(count === len)
resolve(ans)
})
.catch(err=>{
ans[i] = {
status: PRO_STATUS.REJECTED,
reason: err
}
count++
if(count === len)
resolve(ans)
})
}
})
}

2.5、any 实现

传入一个 Promise 类型数组,返回一个 Promise 对象。
当所有 promise 达到 rejected 或 有一个达到 fulfilled 状态,则结束。
如果入参空数组,则返回一个 rejected 的promise,非数组类型入参会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MyPromise.any = function(array) {
if(!Array.isArray(array)) throw new Error('array not Array')
return new MyPromise((resolve, reject)=>{
const ans = []
let count = 0
const len = array.length
if(len ===0) reject(new AggregateError(''))
//
for (let i = 0; i < len; i++) {
const p = array[i];
p.then(res=>{
resolve(res)
})
.catch(err=>{
count++
if(count === len)
reject(ans)
})
}
})
}

3、结语

通过本文的介绍,我们实现了所有 Promise 相关的标准 API 方法。下一节中,我们介绍一些基于 Promise 来实现一些在面试或实际业务中碰到的问题解法。