前言
嗯嗯嗯,等写完这个博客我就去复习期末。
实现过程
基本属性
对一个promise来说,我们需要有下面这些东西
- 对应三个状态的表示
- 当前promise的数据(也就是成功获得的数据或者失败的原因)
- 当前promise的状态
- 成功时要执行的回调函数列表
- 失败时要执行的回调函数列表
另外,为了使用属性私有化,我们要用一个立即执行函数来生成class,然后私有属性全部使用Symbol类型定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const MyPromise = (function () { const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; const PromiseValue = Symbol("PromiseValue"); const PromiseStatus = Symbol("PromiseStatus"); const onFulfilledList = Symbol("onFulfilledList"); const onRejectedList = Symbol("onRejectedList"); return class { constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; } } })();
|
可以看到我们把状态,数据,两个回调列表存到了promise上,然后我们就可以逐步实现一个promise了
完成基础版本
先看看promise最基础的用法
1 2 3
| let promise = new Promise((resolve, reject) => { resolve("sena"); });
|
我们可以看到,在new Promise时,会传入一个函数,这个函数会立即执行,这个函数接收两个参数,分别是resolve和reject,这两个函数是定义好的,这个函数做了下面几件事
- 改变当前promise的状态
- 把传入的参数作为当前promise的数据保存起来
- 执行对应回调列表里里的回调函数
另外要注意的是,promise的状态是不可逆的,只能从pending变成resolved或者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
| const MyPromise = (function () { ...... const updateStatus = Symbol("updateStatus"); return class {
[updateStatus] (newStatus, newValue, executeQueue) { if (this[PromiseStatus] !== PENDING) return; this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; executeQueue.forEach((handler) => { handler(newValue); }) } constructor(executor) { ..... } } })();
|
好了,我们现在已经定义了一个工具函数updateStatus
,但这个工具函数还有一点不好的地方,那就是then绑定的回调函数都是放到微任务中异步执行的,而我们这里是同步执行,在浏览器环境下,没有办法把回调函数放到微任务中,只能放到宏任务队列中异步执行,所以我们还要再更新一下updateStatus
函数
因为把一个回调函数推入宏任务队列也可以抽象一下,所以我们写一个把回调函数推入任务队列的工具函数
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
| const MyPromise = (function () { ...... const updateStatus = Symbol("updateStatus"); const executeAsync = Symbol("executeAsync"); return class {
[executeAsync] (handler, ...arg) { setTimeout(function () { handler(...arg); }, 0) }
[updateStatus] (newStatus, newValue, executeQueue) { ...... executeQueue.forEach((handler) => { this[executeAsync] (handler, newValue); }) } constructor(executor) { ...... } } })();
|
然后我们在构造器中创建resolve和reject两个函数,传入executor即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; const resolve = (data) => { this[updateStatus](RESOLVED, data, this[onFulfilledList]); }; const reject = (reason) => { this[updateStatus](REJECTED, reason, this[onRejectedList]); }; executor && executor(resolve, reject); }
|
这样使用时就可以接收到resolve和reject这两个函数,然后调用他们时,就可以改变promise的状态,然后就可以执行then中注册到回调列表中的函数了。
当然我们还需要做一点小收尾,因为如果传入的executor函数报错,会调用这个promise的reject方法,并把错误信息传入,所以我们需要加一个try catch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; const resolve = (data) => { this[updateStatus](RESOLVED, data, this[onFulfilledList]); }; const reject = (reason) => { this[updateStatus](REJECTED, reason, this[onRejectedList]); }; try { executor && executor(resolve, reject); }catch (e) { reject(e); } }
|
然后看看我们现在已经写好的所有的代码
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
| const MyPromise = (function () { const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; const PromiseValue = Symbol("PromiseValue"); const PromiseStatus = Symbol("PromiseStatus"); const onFulfilledList = Symbol("onFulfilledList"); const onRejectedList = Symbol("onRejectedList"); const updateStatus = Symbol("updateStatus"); const executeAsync = Symbol("executeAsync"); return class {
[executeAsync] (handler, ...arg) { setTimeout(function () { handler(...arg); }, 0) }
[updateStatus] (newStatus, newValue, executeQueue) { if (this[PromiseStatus] !== PENDING) return; this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; executeQueue.forEach((handler) => { this[executeAsync] (handler, newValue); }) } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; const resolve = (data) => { this[updateStatus](RESOLVED, data, this[onFulfilledList]); }; const reject = (reason) => { this[updateStatus](REJECTED, reason, this[onRejectedList]); }; try { executor && executor(resolve, reject); }catch (e) { reject(e); } } } })();
|
测试一下
1 2 3
| let promise = new MyPromise((resolve, reject) => { resolve("sena"); });
|
自然是没有反应的,因为没有then,没有注册回调函数,自然什么也不会发生
实现then
实现then也不难,根据规范,我们需要返回一个promise,因为返回的新promise和现有的promise需要关联,这里我们用一个新的工具函数来创建这个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
| const MyPromise = (function () { ...... const createLinkPromise = Symbol("createLinkPromise"); return class { ......
[createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => {
}); } then(onFulfilled, onRejected) { return this[createLinkPromise](onFulfilled, onRejected); } constructor(executor) { ...... } } })();
|
这里我们使用了一个新的工具函数createLinkPromise
,用于返回一个新的promise,在这里我们会对then的绑定的回调函数进行处理。
实现单个then的绑定事件
then如果传入了回调函数,首先会判断当前promise的状态,如果已经是resolve或者reject状态,就把回调函数推入微任务队列中异步执行,如果还是pending状态,就把回调函数放到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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| const MyPromise = (function () { ...... const settleHandle = Symbol("settleHandle"); return class { ......
[settleHandle] (handler, immediatelyStatus, queue) { if (typeof handler !== "function") return; if (this[PromiseStatus] === immediatelyStatus) { this[executeAsync] (handler, this[PromiseValue]); } else { queue.push(handler); } }
[createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle](resolve, RESOLVED, this[onFulfilledList]); this[settleHandle](reject, REJECTED, this[onRejectedList]); }); } then(onFulfilled, onRejected) { return this[createLinkPromise](onFulfilled, onRejected); }
constructor(executor) { ...... } } })();
|
settleHandle
就是用来处理回调函数的工具函数。
好了,现在我们可以给promise通过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 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
| const MyPromise = (function () { const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; const PromiseValue = Symbol("PromiseValue"); const PromiseStatus = Symbol("PromiseStatus"); const onFulfilledList = Symbol("onFulfilledList"); const onRejectedList = Symbol("onRejectedList"); const updateStatus = Symbol("updateStatus"); const executeAsync = Symbol("executeAsync"); const createLinkPromise = Symbol("createLinkPromise"); const settleHandle = Symbol("settleHandle"); return class {
[executeAsync] (handler, ...arg) { setTimeout(function () { handler(...arg); }, 0) }
[updateStatus] (newStatus, newValue, executeQueue) { if (this[PromiseStatus] !== PENDING) return; this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; executeQueue.forEach((handler) => { this[executeAsync] (handler, newValue); }) }
[settleHandle] (handler, immediatelyStatus, queue) { if (typeof handler !== "function") return; if (this[PromiseStatus] === immediatelyStatus) { this[executeAsync] (handler, this[PromiseValue]); } else { queue.push(handler); } }
[createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle](onFulfilled, RESOLVED, this[onFulfilledList]); this[settleHandle](onRejected, REJECTED, this[onRejectedList]); }); } then(onFulfilled, onRejected) { return this[createLinkPromise](onFulfilled, onRejected); } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; const resolve = (data) => { this[updateStatus](RESOLVED, data, this[onFulfilledList]); }; const reject = (reason) => { this[updateStatus](REJECTED, reason, this[onRejectedList]); }; try { executor && executor(resolve, reject); }catch (e) { reject(e); } } } })();
|
测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| let promise = new MyPromise((resolve, reject) => { setTimeout(function () { resolve("sena"); }, 1000); console.log("123"); }); promise.then(function (data) { console.log(1, data); }); promise.then(function (data) { console.log(2, data); }); promise.then(function (data) { console.log(3, data); });
|
实现then的链式调用
因为then已经返回了一个promise,所以我们要做的事情比较简单,就是处理一下回调函数的返回值和处理回调函数抛出的error就就行了,我们先处理返回值,返回值有两种情况
下文的的下一个Promise代指createLinkPromise
返回的promise
- 返回非promise,直接把返回值通过调用
resolve()
传给下一个promise,下一个promise把这个返回值传给then注册的回调函数,就实现了前一个then的返回值作为下个then的参数
- 返回promise,给返回的promise用then注册成功和失败的回调,在两个回调中分别调用能修改下一个promise的状态的resolve和reject方法,从而完成数据的传递和延时执行
我们看看之前写的代码
1 2 3 4 5 6 7
| [createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle](onFulfilled, RESOLVED, this[onFulfilledList]); this[settleHandle](onRejected, REJECTED, this[onRejectedList]); }); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| [settleHandle] (handler, immediatelyStatus, queue) { if (typeof handler !== "function") return; if (this[PromiseStatus] === immediatelyStatus) { this[executeAsync] (handler, this[PromiseValue]); } else { queue.push(handler); } }
|
很明显,因为我们不知道当前promise的状态,所以我们不知道传入的回调函数声明时候执行,所以要接收返回值,就要做一些特殊处理。
处理的方法也很简单,在回调函数的外面包一层,在外层函数里接收回调函数的返回值就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle]((data) => { let result = onFulfilled(data); resolve(result); }, RESOLVED, this[onFulfilledList]); this[settleHandle]((err) => { let result = onRejected(err); resolve(result); }, REJECTED, this[onRejectedList]); }); }
|
根据规范,如果then传入的onFulfilled函数执行时抛出了错误,就会调用reject函数,所以我们加个try catch在外面,由因为加try catch是重复的逻辑,所以我们可以再抽成一个工具函数execute
。修改后的代码是这样的
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
| const MyPromise = (function () { ...... const execute = Symbol("execute"); return class {
......
[execute] (data, handler, resolve, reject) { try { const result = handler(data); resolve(result); }catch (e) { reject(e); } }
[createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle]((data) => { this[execute](data, onFulfilled, resolve, reject); }, RESOLVED, this[onFulfilledList]); this[settleHandle]((err) => { this[execute](err, onRejected, resolve, reject); }, REJECTED, this[onRejectedList]); }); } constructor(executor) { ...... } } })();
|
现在的代码是这样的
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
| const MyPromise = (function () { const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; const PromiseValue = Symbol("PromiseValue"); const PromiseStatus = Symbol("PromiseStatus"); const onFulfilledList = Symbol("onFulfilledList"); const onRejectedList = Symbol("onRejectedList"); const updateStatus = Symbol("updateStatus"); const executeAsync = Symbol("executeAsync"); const createLinkPromise = Symbol("createLinkPromise"); const settleHandle = Symbol("settleHandle"); const execute = Symbol("execute");
return class {
[executeAsync] (handler, ...arg) { setTimeout(function () { handler(...arg); }, 0) }
[updateStatus] (newStatus, newValue, executeQueue) { if (this[PromiseStatus] !== PENDING) return; this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; executeQueue.forEach((handler) => { this[executeAsync] (handler, newValue); }) }
[settleHandle] (handler, immediatelyStatus, queue) { if (typeof handler !== "function") return; if (this[PromiseStatus] === immediatelyStatus) { this[executeAsync] (handler, this[PromiseValue]); } else { queue.push(handler); } }
[execute] (data, handler, resolve, reject) { try { const result = handler(data); if (result instanceof MyPromise) { result.then((data) => { resolve(data); }, (err) => { reject(err); }) }else { resolve(result); } }catch (e) { reject(e); } }
[createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle]((data) => { this[execute](data, onFulfilled, resolve, reject); }, RESOLVED, this[onFulfilledList]); this[settleHandle]((err) => { this[execute](err, onRejected, resolve, reject); }, REJECTED, this[onRejectedList]); }); } then(onFulfilled, onRejected) { return this[createLinkPromise](onFulfilled, onRejected); } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; const resolve = (data) => { this[updateStatus](RESOLVED, data, this[onFulfilledList]); }; const reject = (reason) => { this[updateStatus](REJECTED, reason, this[onRejectedList]); }; try { executor && executor(resolve, reject); }catch (e) { reject(e); } } } })();
|
好了,现在我们已经处理完了返回值不是promise的情况,让我们测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let promise = new MyPromise((resolve, reject) => { setTimeout(function () { resolve(1); }, 1000); }).then(function (data) { console.log(data); return data + 1; }).then(function (data) { console.log(data); return data + 1; }).then(function (data) { console.log(data); return data + 1; });
|
现在我们来处理返回值是promise的情况,处理的方法原理也不难,给返回的promise注册回调,然后在回调里修改下一个promise的状态就行了
PS:下一个promise指的是createLinkPromise
返回的promise
这里直接修改execute
函数就行了
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
|
[execute] (data, handler, resolve, reject) { try { const result = handler(data); if (result instanceof MyPromise) { result.then((data) => { resolve(data); }, (err) => { reject(err); }) }else { resolve(result); } }catch (e) { reject(e); } }
|
好了,返回值是promise的情况也处理好了,来测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let promise = new MyPromise((resolve, reject) => { setTimeout(function () { resolve("sena"); }, 1000); console.log("sion"); }).then((data) => { console.log("1",data); return data; }).then((data) => { console.log("2",data); return new MyPromise((resolve) => { setTimeout(() => { resolve("sakura"); }, 2000) }); }).then((data) => { console.log("3",data); return data; }); console.log("yyy");
|
输出情况,看起来是正常的
其实到这里,一个promise大致就完成了,接下来就是一些细节处理了
处理空then
如果中间的某个then没有传入回调,虽然我没在规范中找到这种情况(可能是我看漏了),但是在我测试官方promise时回调函数的执行不会中断,所以我们要做些处理
处理的方法也比较简单,如果onFulfilled, onRejected没有传入,使用默认的onFulfilled, onRejected函数,把数据转发就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const MyPromise = (function () { ...... const defaultOnFulfilled = function (data) {return data}; const defaultOnRejected = function (err) {throw new Error(err)}; return class {
then(onFulfilled = defaultOnFulfilled, onRejected = defaultOnRejected) { return this[createLinkPromise](onFulfilled, onRejected); } constructor(executor) { ...... } } })();
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let promise = new MyPromise((resolve, reject) => { setTimeout(function () { resolve("sena"); }, 1000); console.log("sion"); }).then((data) => { console.log("1",data); return data; }).then((data) => { console.log("2",data); return new MyPromise((resolve) => { setTimeout(() => { resolve("sakura"); }, 1000) }); }).then().then((data) => { console.log("3",data); return data; }); console.log("yyy");
|
输出情况
完善promise的其他函数
catch和finally函数
catch其实是特殊的then函数,简单来说就是没有onFulfilled的then函数。
finally也是特殊的then函数,就是无论什么状态都执行相同的回调
所以可以直接调用then来实现
1 2 3 4 5 6
| catch(onRejected) { return this.then(defaultOnFulfilled, onRejected); } finally(handler) { return this.then(handler, handler); }
|
all函数
all函数接收一个promise数组,返回一个promise,只有传入的数据中的所有promise都处于resolved状态后,返回的promise才会处于resolved状态,有任何一个promise处于reject状态后,返回的promise就会处于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
| static all(promises) { let length = promises.length; let resultArr = new Array(length); let count = 0; return new MyPromise((resolve, reject) => { promises.map((promise, index) => { promise.then((data) => { count ++; resultArr[index] = data; if (count >= length) { resolve(resultArr); } }, (err) => { reject(err); }) }) }) }
|
race函数
race函数接收一个promise数组,返回一个promise,返回的promise的状态会与promise数组中的第一个修改状态的项同步修改成相同的值
1 2 3 4 5 6 7 8 9 10 11 12
| static race(promises) { return new MyPromise((resolve, reject) => { promises.forEach((promise) => { promise.then((data) => { resolve(data); }, (err) => { reject(err); }) }) }); }
|
resolve函数
resolve函数返回一个已经处于resolved状态的promise,接收要传给回调函数的data
1 2 3 4 5 6
| static resolve(data) { if (data instanceof MyPromise) return data; return new MyPromise((resolve) => { resolve(data); }) }
|
reject函数
reject函数返回一个已经处于reject状态的promise,接收要传给回调函数的data
1 2 3 4 5 6
| static reject(err) { if (data instanceof MyPromise) return err; return new MyPromise((resolve, reject) => { reject(err); }) }
|
好了,到这里所有的代码就暂时实现完了,当然我后期会再加些方法上去,不过那是以后的事了,最后放一波完整的代码
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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
| const MyPromise = (function () { const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; const PromiseValue = Symbol("PromiseValue"); const PromiseStatus = Symbol("PromiseStatus"); const onFulfilledList = Symbol("onFulfilledList"); const onRejectedList = Symbol("onRejectedList"); const updateStatus = Symbol("updateStatus"); const executeAsync = Symbol("executeAsync"); const createLinkPromise = Symbol("createLinkPromise"); const settleHandle = Symbol("settleHandle"); const execute = Symbol("execute"); const defaultOnFulfilled = function (data) {return data}; const defaultOnRejected = function (err) {throw new Error(err)}; return class {
[executeAsync] (handler, ...arg) { setTimeout(function () { handler(...arg); }, 0) }
[updateStatus] (newStatus, newValue, executeQueue) { if (this[PromiseStatus] !== PENDING) return; this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; executeQueue.forEach((handler) => { this[executeAsync] (handler, newValue); }) }
[settleHandle] (handler, immediatelyStatus, queue) { if (typeof handler !== "function") return; if (this[PromiseStatus] === immediatelyStatus) { this[executeAsync] (handler, this[PromiseValue]); } else { queue.push(handler); } }
[execute] (data, handler, resolve, reject) { try { const result = handler(data); if (result instanceof MyPromise) { result.then((data) => { resolve(data); }, (err) => { reject(err); }) }else { resolve(result); } }catch (e) { reject(e); } }
[createLinkPromise] (onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { this[settleHandle]((data) => { this[execute](data, onFulfilled, resolve, reject); }, RESOLVED, this[onFulfilledList]); this[settleHandle]((err) => { this[execute](err, onRejected, resolve, reject); }, REJECTED, this[onRejectedList]); }); } then(onFulfilled = defaultOnFulfilled, onRejected = defaultOnRejected) { return this[createLinkPromise](onFulfilled, onRejected); } catch(onRejected) { return this.then(defaultOnFulfilled, onRejected); } finally(handler) { return this.then(handler, handler); } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[onFulfilledList] = []; this[onRejectedList] = []; const resolve = (data) => { this[updateStatus](RESOLVED, data, this[onFulfilledList]); }; const reject = (reason) => { this[updateStatus](REJECTED, reason, this[onRejectedList]); }; try { executor && executor(resolve, reject); }catch (e) { reject(e); } } static all(promises) { let length = promises.length; let resultArr = new Array(length); let count = 0; return new MyPromise((resolve, reject) => { promises.map((promise, index) => { promise.then((data) => { count ++; resultArr[index] = data; if (count >= length) { resolve(resultArr); } }, (err) => { reject(err); }) }) }) } static race(promises) { return new MyPromise((resolve, reject) => { promises.forEach((promise) => { promise.then((data) => { resolve(data); }, (err) => { reject(err); }) }) }); } static resolve(data) { if (data instanceof MyPromise) return data; return new MyPromise((resolve) => { resolve(data); }) } static reject(err) { if (data instanceof MyPromise) return err; return new MyPromise((resolve, reject) => { reject(err); }) } } })();
|
感谢你的阅读