手写Promise讲解

整体结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyPromise {
constructor(fn){

}
resolve(){

}
then(){

}
reject(){

}
catch(){

}
}

实现构造函数

1
2
3
4
5
6
7
8
9
10
11
class MyPromise {
constructor(fn){
if(typeof fn !== 'function') {
throw new TypeError(`MyPromise fn ${fn} is not a function`)
}
this.state = 'pending';
this.value = void 0;
fn(this.resolve.bind(this),this.reject.bind(this))
}
...
}

构造函数接收一个参数fn,且这个参数必须是一个函数,因为我们一般这样使用new Promise((resolve,reject)=>{});
然后初始化一下promise的状态,默认开始为pending,初始化value的值。
fn接收两个参数,resolve、reject

resolve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyPromise {
constructor(fn){
if(typeof fn !== 'function') {
throw new TypeError(`MyPromise fn ${fn} is not a function`)
}
this.state = 'pending';
this.value = void 0;
fn(this.resolve.bind(this),this.reject.bind(this))
}
resolve(value){
if(this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value
}
...
}

当resolve执行,接收到一个值之后;状态就由 pending -> fulfilled;当前的值为接收的值

reject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyPromise {
constructor(fn){
if(typeof fn !== 'function') {
throw new TypeError(`MyPromise fn ${fn} is not a function`)
}
this.state = 'pending';
this.value = void 0;
fn(this.resolve.bind(this),this.reject.bind(this))
}
resolve(value){
if(this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value
}
reject(reason){
if(this.state !== 'pending') return;
this.state = 'rejected';
this.value = reason
}
}

当reject执行,接收到一个值之后;状态就由 pending -> rejected;当前的值为接收的值

then

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
class MyPromise {
constructor(fn){
if(typeof fn !== 'function') {
throw new TypeError(`MyPromise fn ${fn} is not a function`)
}
this.state = 'pending';
this.value = void 0;
fn(this.resolve.bind(this),this.reject.bind(this))
}
resolve(value){
if(this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value
}
reject(reason){
if(this.state !== 'pending') return;
this.state = 'rejected';
this.value = reason
}
then(fulfilled,rejected){
if (typeof fulfilled !== 'function' && typeof rejected !== 'function' ) {
return this;
}
if (typeof fulfilled !== 'function' && this.state === 'fulfilled' ||
typeof rejected !== 'function' && this.state === 'rejected') {
return this;
}
return new MyPromise((resolve,reject)=>{
if(fulfilled && typeof fulfilled === 'function' && this.state === 'fulfilled'){
let result = fulfilled(this.value);
if(result && typeof result.then === 'function'){
return result.then(resolve,reject)
}else{
resolve(result)
}
}
if(rejected && typeof rejected === 'function' && this.state === 'rejected'){
let result = rejected(this.value);
if(result && typeof result.then === 'function'){
return result.then(resolve,reject)
}else{
resolve(result)
}
}
})
}
}

then的实现比较关键,首先有两个判断,第一个判断传的两个参数是否都是函数,如果都不是return this执行下一步操作。
第二个判断的作用是,比如,现在状态从pending -> rejected;但是中间代码中有许多个.then的操作,我们需要跳过这些操作执行.catch的代码。如下面的代码,执行结果只会打印1

1
2
3
4
5
6
7
8
9
new Promise((resolve,reject)=>{
reject(1)
}).then(()=>{
console.log(2)
}).then(()=>{
console.log(3)
}).catch((e)=>{
console.log(e)
})

下面有两个判断,作用是判断是rejected还是fulfilled,首先看fulfilled,如果是fulfilled的话,首先执行fulfilled函数,并把当前的value值传过去,也就是下面这步操作,res就是传过去的value值,并执行了(res)=>{console.log(res)}这段代码;执行完成之后我们得到了result;也就是2这个结果,下面就是判断当前结果是否是一个promise实例了,也就是下面注释了的情况,现在我们直接执行resolve(result);

1
2
3
4
5
6
7
new Promise((resolve,reject)=>{
resolve(1)
}).then((res)=>{
console.log(res)
return 2
//return new Promise(resolve=>{})
})

catch

1
2
3
4
5
6
class MyPromise {
...
catch(rejected){
return this.then(null,rejected)
}
}

完成代码

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
class MyPromise {
constructor(fn){
if(typeof fn !== 'function') {
throw new TypeError(`MyPromise fn ${fn} is not a function`)
}
this.state = 'pending';
this.value = void 0;
fn(this.resolve.bind(this),this.reject.bind(this))
}
resolve(value){
if(this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value
}
reject(reason){
if(this.state !== 'pending') return;
this.state = 'rejected';
this.value = reason
}
then(fulfilled,rejected){
if (typeof fulfilled !== 'function' && typeof rejected !== 'function' ) {
return this;
}
if (typeof fulfilled !== 'function' && this.state === 'fulfilled' ||
typeof rejected !== 'function' && this.state === 'rejected') {
return this;
}
return new MyPromise((resolve,reject)=>{
if(fulfilled && typeof fulfilled === 'function' && this.state === 'fulfilled'){
let result = fulfilled(this.value);
if(result && typeof result.then === 'function'){
return result.then(resolve,reject)
}else{
resolve(result)
}
}
if(rejected && typeof rejected === 'function' && this.state === 'rejected'){
let result = rejected(this.value);
if(result && typeof result.then === 'function'){
return result.then(resolve,reject)
}else{
resolve(result)
}
}
})
}
catch(rejected){
return this.then(null,rejected)
}
}
Buy me a cup of coffee,thanks!