在这里插入图片描述

  • 假设自定义Promise类名为HD

  • 首先定义HD中的三种状态:pendingfulfilledrejected
1
2
3
4
5
class HD {
static PENDING = "pending";
static FULFILLED = "fulfilled";
static REJECTED = "rejected";
}

  • 接着咱们来写HD中的构造函数
  1. 首先来看一下是如何创建一个HD对象的
    1
    2
    3
    4
    5
    6
    7
    8
    9
    const myFirstPromise = new Promise((resolve, reject) => {
    // 做一些异步操作,最终会调用下面两者之一(任务完成之后的回调函数):
    //将任务结果通过调用resolve函数或reject函数包装成一个Promise对象

    // resolve(someValue); // fulfilled
    // 或
    // reject("failure reason"); // rejected
    });

  2. 所以构造函数得传过去resolvereject函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class HD {
    constructor(executor) {
    //把状态改为初始状态
    this.status = HD.PENDING;
    this.value = null;

    try {
    // 调用这个函数
    executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
    ***//如果中间出现error,修改为reject状态
    this.reject(error);
    }
    }
    }

  • 书写resolve函数
    1.resolve函数要完成的工作:
      将这个HD对象的状态改为`FULFILLED`
      将这个HD对象的值改为value
    1
    2
    3
    4
    5
    6
    7
    8

    resolve(value) {
    //状态只可以修改一次
    if (this.status == HD.PENDING) {
    this.status = HD.FULFILLED;
    this.value = value;
    }
    }

  • 书写reject函数
    1.reslove函数要完成的工作:
      将这个HD对象的状态改为`REJECTED`
      将这个HD对象的值改为value
    1
    2
    3
    4
    5
    6
    reject(reason) {
    if (this.status == HD.PENDING) {
    this.status = HD.REJECTED;
    this.value = reason;
    }
    }

  • 书写then
  1. 判断是否有传入onFulfilledonRejected函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    then(onFulfilled, onRejected) {
    //如果不传onFulfilled或onRejected函数,要进行判断
    if (typeof onFulfilled != "function") {
    //因为要执行链式操作,所以直接返回this.value
    onFulfilled = () => this.value;
    }
    if (typeof onRejected != "function") {
    onRejected = () => this.value;
    }
    }
  2. 当前状态为准备状态
    因为有异步,如果上一次操作的结果没有出来,直接来调用then,当前的状态就为准备状态。
    所以咱们可以先把需要调用的onFulfilled函数和onRejected函数保存到一个数组中,等到上一次操作结果出来之后,再去调用这两个函数
1
2
3
4
constructor(executor) {
//首先要在构造器中新增一个数组
this.callbacks = [];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
then(onFulfilled, onRejected) {
let promise = new HD((resolve, reject) => {
//【this】代表【调用then的HD对象】
if (this.status == HD.PENDING) {
//将数组中放入这两个函数,以便【调用then的HD对象】出来结果后,可以使用这两个函数
//这里设置了一个对象,onFulfilled和onRejected分别是它的属性
this.callbacks.push({
onFulfilled: value => {
//parse是修改当前HD对象属性的一个函数
//具体是如何修改的,咱们在下面说
this.parse(promise, onFulfilled(value), resolve, reject);
},
onRejected: value => {
this.parse(promise, onRejected(value), resolve, reject);
}
});
}
}
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
//最后咱们从新修改resolve和reject函数
resolve(value) {
if (this.status == HD.PENDING) {
this.status = HD.FULFILLED;
this.value = value;
//当走到这里的时候,value就有值了,可以执行刚才储存在函数里面的内容了。(注意:咱们刚才储存函数的时候,是给【使用this的HD】储存的函数,也就是这里是【使用this的HD】的value有值了)

//因为执行函数【onFulfilled】的时候,需要花时间,所以是异步
//用setTimeout可以模拟异步效果
setTimeout(() => {
//通过value值修改刚才在then里的HD对象的属性
this.callbacks.map(callback => {
callback.onFulfilled(value);
});
});
}
}
reject(reason) {
if (this.status == HD.PENDING) {
this.status = HD.REJECTED;
this.value = reason;

setTimeout(() => {
this.callbacks.map(callback => {
callback.onRejected(reason);
});
});
}
}
  1. 如果当前的状态为成功或失败状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
then(onFulfilled, onRejected) {

//因为then返回的是一个promise
let promise = new HD((resolve, reject) => {
//如果当前状态为成功状态
if (this.status == HD.FULFILLED) {
//因为执行onFulfilled函数需要花时间,所以同样用异步来做
setTimeout(() => {
this.parse(promise, onFulfilled(this.value), resolve, reject);
});
}
//如果当前状态为失败状态
if (this.status == HD.REJECTED) {
setTimeout(() => {
this.parse(promise, onRejected(this.value), resolve, reject);
});
}
});

//返回这个promise
//因为上面有异步操作,所以直接先返回这个promise,就是默认的promise:this.status = HD.PENDING; this.value = null;
//等到异步操作执行完,这两个属性才会改变
return promise;
}

  • 书写parse
    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
    /*
    js中不允许以下操作:
    let promise = new Promise((resolve, reject) => {
    resolve("解决");
    });
    let p = promise.then(value => {
    return p; //因为是异步操作,所以这个p早就有了,不允许返回这个p
    });
    */
    parse(promise, result, resolve, reject) {
    //如果创建的promise对象和结果相同,抛出错误
    if (promise == result) {
    throw new TypeError("Chaining cycle detected");
    }

    try {
    //判断传过来的是否是HD对象
    if (result instanceof HD) {
    result.then(resolve, reject);
    } else {
    resolve(result);
    }
    } catch (error) {
    reject(error);
    }
    }

  • 书写静态resolve方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*  就是
Promise.resolve("后盾人").then(value => {
console.log(value);
});
*/
static resolve(value) {
return new HD((resolve, reject) => {
if (value instanceof HD) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
}

  • 书写reject方法
1
2
3
4
5
static reject(value) {
return new HD((resolve, reject) => {
reject(value);
});
}

  • 书写all方法
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 p1 = new HD(resolve => {
* resolve("后盾人");
* });
*
* let p2 = new HD(resolve => {
* resolve("hdcms");
* });
* HD.all([p1, p2]).then(
* value => {
* console.log(value);
* },
* reason => {
* console.log(reason);
* }
* );
*/
static all(promises) {
const values = [];
//all返回的也是一个promise
return new HD((resolve, reject) => {
promises.forEach(promise => {
//then会检查promise属性,如果成功,就调用第一个函数
//如果失败,就调用第二个函数
promise.then(
//then是对上一个promise的处理,所以只要提供上一个promise,就可以修改属性(状态和值)
value => {
//成功一次就压一次
values.push(value);
if (values.length == promises.length) {
//如若相等,说明所有的promise都跑完了,证明成功了
resolve(values);
}
},
reason => {
reject(reason);
}
);
});
});
}

  • 书写race方法
    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
    //谁快用谁
    /**
    * HD.race([p1, p2]).then{
    * value => {
    * console.log(value);
    * },
    * reason => {
    * console.log(reason);
    * }
    * }
    */
    static race(promises) {
    //返回一个HD对象,resolve和reject是刚才的静态方法
    return new HD((resolve, reject) => {
    promises.map(promise => {
    promise.then(
    value => {
    resolve(value);
    },
    reason => {
    reject(reason);
    }
    );
    });
    });
    }

完整代码:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class HD {
static PENDING = "pending";
static FULFILLED = "fulfilled";
static REJECTED = "rejected";
constructor(executor) {
this.status = HD.PENDING;
this.value = null;

this.callbacks = [];

try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}

resolve(value) {
if (this.status == HD.PENDING) {
this.status = HD.FULFILLED;
this.value = value;

setTimeout(() => {
this.callbacks.map(callback => {
callback.onFulfilled(value);
});
});
}
}
reject(reason) {
if (this.status == HD.PENDING) {
this.status = HD.REJECTED;
this.value = reason;

setTimeout(() => {
this.callbacks.map(callback => {
callback.onRejected(reason);
});
});
}
}


then(onFulfilled, onRejected) {

if (typeof onFulfilled != "function") {
onFulfilled = () => this.value;
}
if (typeof onRejected != "function") {
onRejected = () => this.value;
}

let promise = new HD((resolve, reject) => {

if (this.status == HD.PENDING) {

this.callbacks.push({
onFulfilled: value => {
this.parse(promise, onFulfilled(value), resolve, reject);
},
onRejected: value => {
this.parse(promise, onRejected(value), resolve, reject);
}
});
}


if (this.status == HD.FULFILLED) {
setTimeout(() => {
this.parse(promise, onFulfilled(this.value), resolve, reject);
});
}

if (this.status == HD.REJECTED) {
setTimeout(() => {
this.parse(promise, onRejected(this.value), resolve, reject);
});
}
});
return promise;
}


parse(promise, result, resolve, reject) {
if (promise == result) {
throw new TypeError("Chaining cycle detected");
}


try {
if (result instanceof HD) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}


static resolve(value) {
return new HD((resolve, reject) => {
if (value instanceof HD) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
}

static reject(value) {
return new HD((resolve, reject) => {
reject(value);
});
}


static all(promises) {
const values = [];
return new HD((resolve, reject) => {
promises.forEach(promise => {
promise.then(
value => {
values.push(value);
if (values.length == promises.length) {
resolve(values);
}
},
reason => {
reject(reason);
}
);
});
});
}

static race(promises) {
return new HD((resolve, reject) => {
promises.map(promise => {
promise.then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
);
});
});
}
}