1 // 三种状态
2 const PENDING = "pending";
3 const RESOLVED = "resolved";
4 const REJECTED = "rejected";
5 // promise 接收一个函数参数,该函数会立即执行
6 function MyPromise(fn) {
7 let _this = this;
8 _this.currentState = PENDING;
9 _this.value = undefined;
10 // 用于保存 then 中的回调,只有当 promise
11 // 状态为 pending 时才会缓存,并且每个实例至多缓存一个
12 _this.resolvedCallbacks = [];
13 _this.rejectedCallbacks = [];
14
15 _this.resolve = function (value) {
16 if (value instanceof MyPromise) {
17 // 如果 value 是个 Promise,递归执行
18 return value.then(_this.resolve, _this.reject)
19 }
20 setTimeout(() => { // 异步执行,保证执行顺序
21 if (_this.currentState === PENDING) {
22 _this.currentState = RESOLVED;
23 _this.value = value;
24 _this.resolvedCallbacks.forEach(cb => cb());
25 }
26 })
27 };
28
29 _this.reject = function (reason) {
30 setTimeout(() => { // 异步执行,保证执行顺序
31 if (_this.currentState === PENDING) {
32 _this.currentState = REJECTED;
33 _this.value = reason;
34 _this.rejectedCallbacks.forEach(cb => cb());
35 }
36 })
37 }
38 // 用于解决以下问题
39 // new Promise(() => throw Error('error))
40 try {
41 fn(_this.resolve, _this.reject);
42 } catch (e) {
43 _this.reject(e);
44 }
45 }
46
47 MyPromise.prototype.then = function (onResolved, onRejected) {
48 var self = this;
49 // 规范 2.2.7,then 必须返回一个新的 promise
50 var promise2;
51 // 规范 2.2.onResolved 和 onRejected 都为可选参数
52 // 如果类型不是函数需要忽略,同时也实现了透传
53 // Promise.resolve(4).then().then((value) => console.log(value))
54 onResolved = typeof onResolved === 'function' ? onResolved : v => v;
55 onRejected = typeof onRejected === 'function' ? onRejected : r => throw r;
56
57 if (self.currentState === RESOLVED) {
58 return (promise2 = new MyPromise(function (resolve, reject) {
59 // 规范 2.2.4,保证 onFulfilled,onRjected 异步执行
60 // 所以用了 setTimeout 包裹下
61 setTimeout(function () {
62 try {
63 var x = onResolved(self.value);
64 resolutionProcedure(promise2, x, resolve, reject);
65 } catch (reason) {
66 reject(reason);
67 }
68 });
69 }));
70 }
71
72 if (self.currentState === REJECTED) {
73 return (promise2 = new MyPromise(function (resolve, reject) {
74 setTimeout(function () {
75 // 异步执行onRejected
76 try {
77 var x = onRejected(self.value);
78 resolutionProcedure(promise2, x, resolve, reject);
79 } catch (reason) {
80 reject(reason);
81 }
82 });
83 }));
84 }
85
86 if (self.currentState === PENDING) {
87 return (promise2 = new MyPromise(function (resolve, reject) {
88 self.resolvedCallbacks.push(function () {
89 // 考虑到可能会有报错,所以使用 try/catch 包裹
90 try {
91 var x = onResolved(self.value);
92 resolutionProcedure(promise2, x, resolve, reject);
93 } catch (r) {
94 reject(r);
95 }
96 });
97
98 self.rejectedCallbacks.push(function () {
99 try {
100 var x = onRejected(self.value);
101 resolutionProcedure(promise2, x, resolve, reject);
102 } catch (r) {
103 reject(r);
104 }
105 });
106 }));
107 }
108 };
109 // 规范 2.3
110 function resolutionProcedure(promise2, x, resolve, reject) {
111 // 规范 2.3.1,x 不能和 promise2 相同,避免循环引用
112 if (promise2 === x) {
113 return reject(new TypeError("Error"));
114 }
115 // 规范 2.3.2
116 // 如果 x 为 Promise,状态为 pending 需要继续等待否则执行
117 if (x instanceof MyPromise) {
118 if (x.currentState === PENDING) {
119 x.then(function (value) {
120 // 再次调用该函数是为了确认 x resolve 的
121 // 参数是什么类型,如果是基本类型就再次 resolve
122 // 把值传给下个 then
123 resolutionProcedure(promise2, value, resolve, reject);
124 }, reject);
125 } else {
126 x.then(resolve, reject);
127 }
128 return;
129 }
130 // 规范 2.3.3.3.3
131 // reject 或者 resolve 其中一个执行过得话,忽略其他的
132 let called = false;
133 // 规范 2.3.3,判断 x 是否为对象或者函数
134 if (x !== null && (typeof x === "object" || typeof x === "function")) {
135 // 规范 2.3.3.2,如果不能取出 then,就 reject
136 try {
137 // 规范 2.3.3.1
138 let then = x.then;
139 // 如果 then 是函数,调用 x.then
140 if (typeof then === "function") {
141 // 规范 2.3.3.3
142 then.call(
143 x,
144 y => {
145 if (called) return;
146 called = true;
147 // 规范 2.3.3.3.1
148 resolutionProcedure(promise2, y, resolve, reject);
149 },
150 e => {
151 if (called) return;
152 called = true;
153 reject(e);
154 }
155 );
156 } else {
157 // 规范 2.3.3.4
158 resolve(x);
159 }
160 } catch (e) {
161 if (called) return;
162 called = true;
163 reject(e);
164 }
165 } else {
166 // 规范 2.3.4,x 为基本类型
167 resolve(x);
168 }
169 }