# 源码

(function (window) {
    /**
     * 问题:未指定捕获异常的回调,不抛出异常
     */
    const PENDING = "pending";
    const FULFILLED = "fulfilled";
    const REJECTED = "rejected";

    function Promise(executor) {
        // 存储状态
        this.status = PENDING;
        // 存储结果
        this.data = undefined;
        // 存储回调 { onFulfilled, onRejected }
        this.callbacks = [];
        this.resolve = value => {
            if (this.status === 'pending') {
                this.status = FULFILLED;
                this.data = value;
                // 模拟异步
                setTimeout(() => {
                    if (this.callbacks.length > 0) {
                        // 遍历执行回调
                        this.callbacks.forEach(callbacksObj => {
                            callbacksObj.onFulfilled(value);
                        });
                    }
                });
            }
        };
        this.reject = reason => {
            if (this.status === 'pending') {
                this.status = REJECTED;
                this.data = reason;
                // 模拟异步
                setTimeout(() => {
                    if (this.callbacks.length > 0) {
                        // 遍历执行回调
                        this.callbacks.forEach(callbacksObj => {
                            callbacksObj.onRejected(reason);
                        });
                    }
                });
            }
        };

        // 捕获抛出的异常
        try {
            executor(this.resolve, this.reject);
        } catch (err) {
            this.reject(err);
        }
    }

    Promise.prototype.then = function (onFulfilled, onRejected) {
        // 判断是函数还是一个常量
        onFulfilled =
            typeof onFulfilled === "function" ? onFulfilled : value => value;
        // 错误穿透
        onRejected =
            typeof onRejected === "function"
                ? onRejected
                : reason => {
                    throw reason;
                };
        // 返回promise,状态由回调return的结果决定
        return new Promise((resolve, reject) => {
            // 处理函数
            const handle = callback => {
                // result返回值:promise、非promise、抛出异常
                try {
                    const result = callback(this.data);
                    // 回调结果是一个promise,结果由这个promise决定
                    if (result instanceof Promise) {
                        result.then(resolve, reject);
                    } else {
                        // 回调结果不是一个promise,直接resolve
                        resolve(result);
                    }
                } catch (err) {
                    reject(err);
                }
            };

            const status = this.status;
            // 状态为pending,放到回调中,状态改变了再遍历执行
            if (status === PENDING) {
                this.callbacks.push({
                    onFulfilled: () => {
                        handle(onFulfilled);
                    },
                    onRejected: () => {
                        handle(onRejected);
                    }
                });
            } else if (status === FULFILLED) {
                // 直接执行
                // 模拟异步执行
                setTimeout(() => {
                    handle(onFulfilled);
                });
            } else {
                // 直接执行
                // 模拟异步执行
                setTimeout(() => {
                    handle(onRejected);
                });
            }
        });
    };

    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected);
    };

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

    Promise.reject = function (reason) {
        return new Promise((resolve, reject) => {
            reject(reason);
        });
    };

    Promise.all = function (promises) {
        return new Promise((reslove, reject) => {
            // 存储结果
            const values = new Array(promises.length);
            // 计数
            let count = 0;
            promises.forEach((promise, index) => {
                Promise.resolve(promise).then(
                    value => {
                        values[index] = value;
                        count++;
                        if (count === promises.length) {
                            reslove(values)
                        }
                    },
                    reason => {
                        reject(reason);
                    }
                );
            });
        });
    };

    Promise.race = function (promises) {
        return new Promise((resolve, reject) => {
            promises.forEach(promise => {
                Promise.resolve(promise).then(
                    resolve,
                    reject
                );
            });
        })
    };

    window.Promise = Promise;
})(window);

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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168