当前位置: 首页 > article >正文

js 手写promise

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';class MyPromise {#status = PENDING;#result = undefined;#handler = undefined;constructor(executor) {// 不能写在外面,因为this指向会出问题const resolve = (data) => {this.#changeState(FULFILLED, data);}const reject = (err) => {this.#changeState(REJECTED, err);}try {executor(resolve, reject);} catch(err) {reject(err); }}#changeState (status, result) {if (this.#status !== PENDING) {return;}this.#status = status;this.#result = result;this.#run();}#run () {console.log(this, this.#handler);if (this.status === PENDING) {return;}const { onFulfilled, onRejected, resolve, reject } = this.#handler;// 回调不是函数,那么将当前的promise状态透传// 回调是函数,将函数执行返回值作为新的值传递,状态变为成功,执行过程报错,那么状态就为失败if(this.#status === FULFILLED) {if (typeof onFulfilled === 'function') {try {const res = onFulfilled(this.#result);resolve(res);} catch (err) {reject(err);}} else {resolve(this.#result);}} else {if (typeof onRejected === 'function') {try {const res = onRejected(this.#result);resolve(res);} catch (err) {reject(err);}} else {reject(this.#result);}}}then(onFulfilled, onRejected) {return  new MyPromise((resolve, reject) => {this.#handler = { onFulfilled, onRejected, resolve, reject };this.#run();});}
}const p = new Promise((resolve, reject) => {// setTimeout(() => {reject(222);// }, 0);// resolve(111);// throw 123;// setTimeout(() => {//     throw 123;  // 异步错误捕获不到,Promise也是一样// }, 0);
});p.then((res) => {console.log('成功1', res);
}, (err) => {console.log('失败1', err);return 333;
}).then(1, (err) => {console.log('失败2', err);
}).then((res) => {console.log('成功3', res);
}, (err) => {console.log('失败3', err);
}).then((res) => {console.log('成功4', res);
}, (err) => {console.log('失败4', err);
});const p1 = new MyPromise((resolve, reject) => {// setTimeout(() => {reject(222);// }, 0);// resolve(111);// throw 123;// setTimeout(() => {//     throw 123;  // 异步错误捕获不到,Promise也是一样// }, 0);
});p1.then((res) => {console.log('成功1', res);
}, (err) => {console.log('失败1', err);return 333;
}).then(1, (err) => {console.log('失败2', err);
}).then((res) => {console.log('成功3', res);
}, (err) => {console.log('失败3', err);
}).then((res) => {console.log('成功4', res);
}, (err) => {console.log('失败4', err);
});

其他静态方法

	static resolve(value) {return new MyPromise((resolve) => resolve(value));}static reject(reason) {return new MyPromise((resolve, reject) => reject(reason));}static all(promises) {// 问题关键: 什么时候要执行resolve, 什么时候要执行rejectreturn new MyPromise((resolve, reject) => {const values = [];promises.forEach((promise) => {promise.then((res) => {values.push(res);if (values.length === promises.length) {resolve(values);}},(err) => {reject(err);},);});});}static allSettled(promises) {return new MyPromise((resolve) => {const results = [];promises.forEach((promise) => {promise.then((res) => {results.push({ status: PROMISE_STATUS_FULFILLED, value: res });if (results.length === promises.length) {resolve(results);}},(err) => {results.push({ status: PROMISE_STATUS_REJECTED, value: err });if (results.length === promises.length) {resolve(results);}},);});});}static race(promises) {return new MyPromise((resolve, reject) => {promises.forEach((promise) => {promise.then(resolve, reject);});});}static any(promises) {// resolve必须等到有一个成功的结果// reject所有的都失败才执行rejectconst reasons = [];return new MyPromise((resolve, reject) => {promises.forEach((promise) => {promise.then(resolve, (err) => {reasons.push(err);if (reasons.length === promises.length) {reject(new AggregateError(reasons));}});});});}
http://www.lryc.cn/news/2392219.html

相关文章:

  • HTTP 与 HTTPS 深度解析:原理、实践与大型项目应用
  • QT6.9中opencv引用路径的其中一种设置
  • k8s pod启动失败问题排查
  • Java类中各部分内容的加载执行顺序
  • git提交信息错误,如何修改远程git提交的备注信息
  • API Gateway CLI 实操入门笔记(基于 LocalStack)
  • 基于MATLAB实现SFA(Slow Feature Analysis,慢特征分析)算法
  • 数据分析案例-基于红米和华为手机的用户评论分析
  • leetcode617.合并二叉树:递归思想下的树结构融合艺术
  • 深度学习入门:从零搭建你的第一个神经网络
  • 【HTML-13】HTML表格合并技术详解:打造专业数据展示
  • 鸿蒙OSUniApp 制作自定义的进度条组件#三方框架 #Uniapp
  • 【Python办公】Excel简易透视办公小工具
  • m1 运行renrenfastvue出现的问题和解决方案
  • 开源模型应用落地-qwen模型小试-Qwen3-8B-推理加速-vLLM-Docker(二)
  • 【C/C++】记录一次麻烦的Kafka+Json体验
  • Linux系列-2 Shell常用命令收集
  • MATLAB使用多个扇形颜色变化表示空间一个点的多种数值
  • mysql:MVCC机制
  • Vue3 + Element Plus 实现树形结构的“单选 + 只选叶子节点 + 默认选中第一个子节点”
  • CAD精简多段线顶点、优化、删除多余、重复顶点——CAD c#二次开发
  • 输电线路的“智慧之眼”:全天候可视化监测如何赋能电网安全运维
  • Spring 核心知识点补充
  • 两阶段法目标检测发展脉络
  • Flannel 支持的后端
  • 小白的进阶之路系列之六----人工智能从初步到精通pytorch数据集与数据加载器
  • SQL进阶之旅 Day 5: 常用函数与表达式
  • NestJS——重构日志、数据库、配置
  • c++数据结构8——二叉树的性质
  • Window Server 2019--08 网络负载均衡与Web Farm