1. /**
    2. * promise 的 三种状态
    3. */
    4. const PENDING = "PENDING",
    5. FULFILLED = "FULFILLED",
    6. REJECED = "REJECTED";
    7. /**
    8. *
    9. * @param {*} p2 p2 就是promise
    10. * @param {*} x onFulfilled 或者 onRejected的返回值
    11. * @param {*} resolve
    12. * @param {*} reject
    13. * @returns
    14. */
    15. function resolvePromise(p2, x, resolve, reject) {
    16. // console.log(p2===x);
    17. if (p2 === x) {
    18. // 解决循环引用
    19. return reject(new TypeError(" Chaining cycle detected for promise #<MyPromiseFinal>"))
    20. }
    21. // called 是否已经调用过resolve 或者是reject
    22. let called = false;
    23. // 2.3.3
    24. if ((typeof x === "object" && x !== null) || typeof x === "function") {
    25. try {
    26. // 获取then的时候可能被劫持 Object.defineProperty 中被劫持
    27. let then = x.then;
    28. if (typeof then === "function") {
    29. // Promise 可以断定
    30. then.call(x, (y) => {
    31. if (called) return;
    32. called = true;
    33. // y可能是 MyPromise对象
    34. resolvePromise(p2, y, resolve, reject);
    35. // resolve(y);
    36. }, (r) => {
    37. if (called) return;
    38. called = true;
    39. reject(r);
    40. })
    41. } else {
    42. resolve(x);
    43. }
    44. } catch (error) {
    45. if (called) return;
    46. called = true;
    47. reject(error);
    48. }
    49. } else {
    50. resolve(x);
    51. }
    52. }
    53. /**
    54. *
    55. * @param {*} x 判断x是否是promise
    56. * @returns
    57. */
    58. function isPromise(x){
    59. if((typeof x === "object" && x !== null) || typeof x === "function"){
    60. try {
    61. let then = x.then;
    62. if(typeof then === "function"){
    63. return true;
    64. }else{
    65. return false;
    66. }
    67. } catch (error) {
    68. return false;
    69. }
    70. }
    71. return false;
    72. }
    73. /**
    74. *
    75. * @param {data} data
    76. * @returns 判断数据是否是可迭代对象
    77. */
    78. function isIterable(data){
    79. return data !== null && data !== undefined && typeof data[Symbol.iterator] === 'function'
    80. }
    81. class MyPromiseFinal {
    82. constructor(fn) {
    83. // 初始化状态
    84. this.status = PENDING;
    85. // 成功值
    86. this.value = undefined;
    87. // 失败的元婴赋值为
    88. this.reason = undefined;
    89. // 成功态的回调函数集合
    90. this.onFulFilledCallbacks = [];
    91. // 失败态的回调函数集合
    92. this.onRejectedCallbacks = [];
    93. // 将promise 从 pending -> resolve的状态
    94. let resolve = (value) => {
    95. // 判断是否是thenable对象
    96. if(value instanceof MyPromiseFinal){
    97. // 如果value 还是 MyPromiseFinal的实例 那么久执行then
    98. // 如果还是MyPromiseFinal 那么继续走resolve 直到不是promise为止
    99. return value.then(resolve,reject);
    100. }
    101. if (this.status === PENDING) {
    102. this.status = FULFILLED;
    103. this.value = value;
    104. // 发布
    105. this.onFulFilledCallbacks.forEach(fn => fn());
    106. }
    107. }
    108. // 将promise 从 pending -> rejected的状态 赋值原因
    109. let reject = (reason) => {
    110. if (this.status === PENDING) {
    111. this.status = REJECED;
    112. this.reason = reason;
    113. // 发布
    114. this.onRejectedCallbacks.forEach(fn => fn());
    115. }
    116. }
    117. // executor
    118. fn(resolve, reject);
    119. }
    120. // x 可能是 1 字符串1 bool 类型 但是可能是 Promise
    121. then(onFulFilled, onRejected) {
    122. // then 穿透 onFulfilled onRejected 是可选参数
    123. onFulFilled = typeof onFulFilled === "function" ? onFulFilled : value => value; //直接返回成功态的值
    124. onRejected = typeof onRejected === "function" ? onRejected : reason => { throw (reason) };
    125. // then 必须返回一个promise对象
    126. let promise2 = new MyPromiseFinal((resolve, reject) => {
    127. if (this.status === FULFILLED) {
    128. // 为什么使用 setTimeout 参考promiseA+ 3.1
    129. setTimeout(() => {
    130. // if (called) return;
    131. // called = true;
    132. try {
    133. let x = onFulFilled(this.value);// 可能onFulFilled 抛出错误
    134. resolvePromise(promise2, x, resolve, reject);
    135. } catch (error) {
    136. reject(error)
    137. }
    138. }, 0);
    139. }
    140. if (this.status === REJECED) {
    141. setTimeout(() => {
    142. // if (called) return;
    143. // called = true;
    144. try {
    145. let x = onRejected(this.reason);
    146. resolvePromise(promise2, x, resolve, reject);
    147. } catch (error) {
    148. reject(error)
    149. }
    150. }, 0);
    151. }
    152. if (this.status === PENDING) {
    153. this.onFulFilledCallbacks.push(() => {
    154. setTimeout(() => {
    155. try {
    156. let x = onFulFilled(this.value);
    157. resolvePromise(promise2, x, resolve, reject);
    158. } catch (error) {
    159. reject(error)
    160. }
    161. }, 0);
    162. })
    163. this.onRejectedCallbacks.push(() => {
    164. setTimeout(() => {
    165. try {
    166. let x = onRejected(this.reason);
    167. resolvePromise(promise2, x, resolve, reject);
    168. } catch (error) {
    169. reject(error)
    170. }
    171. }, 0);
    172. })
    173. }
    174. });
    175. return promise2
    176. }
    177. catch(reject) {
    178. return this.then(null, reject)
    179. }
    180. /**
    181. * Promise.reoslve("common value").finally(()=>{
    182. * console.log(1);
    183. * return new Promise((resolve,reject)=>{
    184. * reject(123);
    185. * })
    186. * }).then(data=>{
    187. * console.log(data);
    188. * }).catch(err=>console.log(err))
    189. */
    190. finally(finallyCallback){
    191. return this.then((value)=>{
    192. return MyPromiseFinal.resolve(finallyCallback()).then(()=>{
    193. return value
    194. })
    195. },(reason)=>{
    196. return MyPromiseFinal.resolve(finallyCallback()).then(()=>{
    197. throw reason
    198. })
    199. })
    200. }
    201. static resolve(value){
    202. return new MyPromiseFinal((resolve,reject)=>{
    203. resolve(value);
    204. })
    205. }
    206. static reject(reason){
    207. return new MyPromiseFinal((resolve,reject)=>{
    208. reject(reason);
    209. })
    210. }
    211. static all(promiseArr){
    212. let id = 0,
    213. resArr =[];
    214. function formatPromise(value,idx,resolve){
    215. resArr[idx] = value;
    216. if(++id === promiseArr.length){
    217. resolve(resArr);
    218. }
    219. }
    220. return new MyPromiseFinal((resolve,reject)=>{
    221. promiseArr.forEach((promise,idx)=>{
    222. if(isPromise(promise)){
    223. promise.then((value)=>{
    224. formatPromise(value,idx,resolve);
    225. },reject)
    226. }else{
    227. formatPromise(promise,idx,resolve);
    228. }
    229. })
    230. })
    231. }
    232. static race(promiseArr){
    233. let res;
    234. function formatRacePromise (x,resolve,reject){
    235. if(res)return;
    236. res = x;
    237. if(resolve){
    238. resolve(x);
    239. }else{
    240. reject(x);
    241. }
    242. }
    243. return new MyPromiseFinal((resolve,reject)=>{
    244. promiseArr.map((promise,idx)=>{
    245. if(isPromise(promise)){
    246. promise.then((res)=>{
    247. formatRacePromise(res,resolve,reject);
    248. },(reason) =>{
    249. formatRacePromise(reason,null,reject);
    250. // reject(reason)
    251. })
    252. }else{
    253. resolve(promise);
    254. }
    255. })
    256. })
    257. }
    258. static race2(promiseArr){
    259. return new MyPromiseFinal((resolve,reject)=>{
    260. promiseArr.map((promise,idx) => {
    261. if(isPromise(promise)){
    262. promise.then(resolve,reject);
    263. }
    264. })
    265. })
    266. }
    267. static allSettled(promiseArr){
    268. let resArr = [],
    269. idx = 0;
    270. function handlePromiseRes(status,value,resolve){
    271. switch(status){
    272. case "fulfilled":
    273. resArr.push({
    274. status,
    275. value
    276. });
    277. break;
    278. case "rejected":
    279. resArr.push({
    280. status,
    281. reason:value
    282. })
    283. }
    284. if(++idx === promiseArr.length){
    285. resolve(resArr);
    286. }
    287. }
    288. return new MyPromiseFinal((resolve,reject)=>{
    289. if(!isIterable(promiseArr)){
    290. throw new TypeError(promiseArr +" is not iterable (cannot read property Symbol(Symbol.iterator))")
    291. }
    292. if(promiseArr.length===0){
    293. resolve(resArr);
    294. }
    295. promiseArr.map((promise,idx)=>{
    296. if(isPromise(promise)){
    297. promise.then((value)=>{
    298. handlePromiseRes("fulfilled",value, resolve);
    299. },(reason) =>{
    300. handlePromiseRes("rejected",reason, resolve);
    301. })
    302. }else{
    303. handlePromiseRes("fulfilled",promise, resolve);
    304. }
    305. })
    306. })
    307. }
    308. }
    309. // 检测Promise 是否符合promiseA+规范
    310. MyPromiseFinal.defer = MyPromiseFinal.deferred = function () {
    311. let deferred = {};
    312. deferred.promise = new MyPromiseFinal((resolve, reject) => {
    313. deferred.resolve = resolve;
    314. deferred.reject = reject;
    315. })
    316. return deferred;
    317. }
    318. module.exports = MyPromiseFinal;
    319. // 循环 引用的例子
    320. /* let cycleP = new Promise((resolve,reject)=>{
    321. resolve("123")
    322. })
    323. let cycleP2 = cycleP.then(data=>{
    324. return cycleP2
    325. }) */