js 手写promise

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
  1. const PENDING = 'pending';
  2. const FULFILLED = 'fulfilled';
  3. const REJECTED = 'rejected';
  4. class MyPromise {
  5.     #status = PENDING;
  6.     #result = undefined;
  7.     #handler = undefined;
  8.     constructor(executor) {
  9.         // 不能写在外面,因为this指向会出问题
  10.         const resolve = (data) => {
  11.             this.#changeState(FULFILLED, data);
  12.         }
  13.         const reject = (err) => {
  14.             this.#changeState(REJECTED, err);
  15.         }
  16.    
  17.         try {
  18.             executor(resolve, reject);
  19.         } catch(err) {
  20.             reject(err);
  21.         }
  22.     }
  23.     #changeState (status, result) {
  24.         if (this.#status !== PENDING) {
  25.             return;
  26.         }
  27.         this.#status = status;
  28.         this.#result = result;
  29.         this.#run();
  30.     }
  31.     #run () {
  32.         console.log(this, this.#handler);
  33.         if (this.status === PENDING) {
  34.             return;
  35.         }
  36.         const { onFulfilled, onRejected, resolve, reject } = this.#handler;
  37.         // 回调不是函数,那么将当前的promise状态透传
  38.         // 回调是函数,将函数执行返回值作为新的值传递,状态变为成功,执行过程报错,那么状态就为失败
  39.         if(this.#status === FULFILLED) {
  40.             if (typeof onFulfilled === 'function') {
  41.                 try {
  42.                     const res = onFulfilled(this.#result);
  43.                     resolve(res);
  44.                 } catch (err) {
  45.                     reject(err);
  46.                 }
  47.             } else {
  48.                 resolve(this.#result);
  49.             }
  50.         } else {
  51.             if (typeof onRejected === 'function') {
  52.                 try {
  53.                     const res = onRejected(this.#result);
  54.                     resolve(res);
  55.                 } catch (err) {
  56.                     reject(err);
  57.                 }
  58.             } else {
  59.                 reject(this.#result);
  60.             }
  61.         }
  62.     }
  63.     then(onFulfilled, onRejected) {
  64.         return  new MyPromise((resolve, reject) => {
  65.             this.#handler = { onFulfilled, onRejected, resolve, reject };
  66.             this.#run();
  67.         });
  68.     }
  69. }
  70. const p = new Promise((resolve, reject) => {
  71.     // setTimeout(() => {
  72.         reject(222);
  73.     // }, 0);
  74.     // resolve(111);
  75.     // throw 123;
  76.     // setTimeout(() => {
  77.     //     throw 123;  // 异步错误捕获不到,Promise也是一样
  78.     // }, 0);
  79. });
  80. p.then((res) => {
  81.     console.log('成功1', res);
  82. }, (err) => {
  83.     console.log('失败1', err);
  84.     return 333;
  85. }).then(1, (err) => {
  86.     console.log('失败2', err);
  87. }).then((res) => {
  88.     console.log('成功3', res);
  89. }, (err) => {
  90.     console.log('失败3', err);
  91. }).then((res) => {
  92.     console.log('成功4', res);
  93. }, (err) => {
  94.     console.log('失败4', err);
  95. });
  96. const p1 = new MyPromise((resolve, reject) => {
  97.     // setTimeout(() => {
  98.         reject(222);
  99.     // }, 0);
  100.     // resolve(111);
  101.     // throw 123;
  102.     // setTimeout(() => {
  103.     //     throw 123;  // 异步错误捕获不到,Promise也是一样
  104.     // }, 0);
  105. });
  106. p1.then((res) => {
  107.     console.log('成功1', res);
  108. }, (err) => {
  109.     console.log('失败1', err);
  110.     return 333;
  111. }).then(1, (err) => {
  112.     console.log('失败2', err);
  113. }).then((res) => {
  114.     console.log('成功3', res);
  115. }, (err) => {
  116.     console.log('失败3', err);
  117. }).then((res) => {
  118.     console.log('成功4', res);
  119. }, (err) => {
  120.     console.log('失败4', err);
  121. });
复制代码
其他静态方法
  1.         static resolve(value) {
  2.         return new MyPromise((resolve) => resolve(value));
  3.     }
  4.     static reject(reason) {
  5.         return new MyPromise((resolve, reject) => reject(reason));
  6.     }
  7.     static all(promises) {
  8.         // 问题关键: 什么时候要执行resolve, 什么时候要执行reject
  9.         return new MyPromise((resolve, reject) => {
  10.             const values = [];
  11.             promises.forEach((promise) => {
  12.                 promise.then(
  13.                     (res) => {
  14.                         values.push(res);
  15.                         if (values.length === promises.length) {
  16.                             resolve(values);
  17.                         }
  18.                     },
  19.                     (err) => {
  20.                         reject(err);
  21.                     },
  22.                 );
  23.             });
  24.         });
  25.     }
  26.     static allSettled(promises) {
  27.         return new MyPromise((resolve) => {
  28.             const results = [];
  29.             promises.forEach((promise) => {
  30.                 promise.then(
  31.                     (res) => {
  32.                         results.push({ status: PROMISE_STATUS_FULFILLED, value: res });
  33.                         if (results.length === promises.length) {
  34.                             resolve(results);
  35.                         }
  36.                     },
  37.                     (err) => {
  38.                         results.push({ status: PROMISE_STATUS_REJECTED, value: err });
  39.                         if (results.length === promises.length) {
  40.                             resolve(results);
  41.                         }
  42.                     },
  43.                 );
  44.             });
  45.         });
  46.     }
  47.     static race(promises) {
  48.         return new MyPromise((resolve, reject) => {
  49.             promises.forEach((promise) => {
  50.                 promise.then(resolve, reject);
  51.             });
  52.         });
  53.     }
  54.     static any(promises) {
  55.         // resolve必须等到有一个成功的结果
  56.         // reject所有的都失败才执行reject
  57.         const reasons = [];
  58.         return new MyPromise((resolve, reject) => {
  59.             promises.forEach((promise) => {
  60.                 promise.then(resolve, (err) => {
  61.                     reasons.push(err);
  62.                     if (reasons.length === promises.length) {
  63.                         reject(new AggregateError(reasons));
  64.                     }
  65.                 });
  66.             });
  67.         });
  68.     }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5

GMT+8, 2025-7-25 08:20 , Processed in 0.085713 second(s), 29 queries 手机版|qidao123.com技术社区-IT企服评测▪应用市场 ( 浙ICP备20004199 )|网站地图

快速回复 返回顶部 返回列表