实现Promise的resolve/reject/then/all/race/finally/catch方法
promise实现基本思路和基本原理:
1.Promise三种状态Pending-等待 Fulfilled-成功 Rejected-失败
2.Promise中的状态使用resolve和reject 2个函数改变状态 并且是不可逆
3.executer如果有错误代码 那么Promise的状态会修改为rejected状态
4.Promise传入一个参数executer执行器,有两个参数分别是resolve和reject函数
5.then方法传入两个参数,分别是onFulfilled和onReject两个函数,当Promise内部状态改变时,调用相关状态回调函数
6.多次调用then方法思路:
(1) 多次调用then方法,应该把onFulfilled和onReject方法缓存
(2) 当Promise状态改变时,去触发相应状态缓存的方法
(3) 发布订阅模式
7.then实现链式调用
(1) 链式调用返回一个Promise
(2) then如果返回是一个普通值,那么作为下一个then的结果
(3) then抛出异常 那么作为下一个then的失败结果
(4) then返回是一个Promise 需要等待这个Promise执行完
8.catch的实现,其实就是将then方法中的第二个参数onReject实现报错调用
9.finally的实现,无论是成功还是失败都会调用执行
10.Promise.all 原理:当传入的数组每一个promise调用结果状态都是成功,那么返回一个数组包含入参返回值
11.Promise.race 原理:当传入的数组每一个promise调用,返回值由最快改变状态的Promise决定
代码实现
1.定义Promise三种状态和调用executer函数执行,定义status、value 、callbacks 等类成员变量,处理有可能报错
class MyPromise {static PENDING = 'pending';static FULFILLED = 'fulfilled';static REJECTED = 'rejected';constructor(executer) {//初始状态this.status = MyPromise.PENDING;//初始值this.value = null;//等待状态成功和失败函数暂时存放起来this.callbacks = [];//传入的函数 resolve 和 reject参数try {executer(this.resolve.bind(this), this.reject.bind(this));} catch (error) {this.reject.bind(this, error);}}}
2.实现类resolve和reject方法
resolve(val) {//只有pending状态才会改变if (this.status === MyPromise.PENDING) {this.status = MyPromise.FULFILLED;this.value = val;//多次触发then和异步处理方案setTimeout(() => {this.callbacks.map((callback) => {callback.onFulfilled(val);});});}}reject(reason) {//只有pending状态才会改变if (this.status === MyPromise.PENDING) {this.status = MyPromise.REJECTED;this.value = reason;//多次触发then和异步处理方案setTimeout(() => {this.callbacks.map((callback) => {callback.onReject(reason);});});}}
3.实现类then的方法和链式调用
then(onFulfilled = (val) => val,onReject = (reason) => {throw reason;}) {const promise = new MyPromise((resolve, reject) => {switch (this.status) {//等待状态case MyPromise.PENDING:this.callbacks.push({onFulfilled: (val) => {try {const res = onFulfilled(val);this.resolvePromise(promise, res, resolve, reject);} catch (error) {reject(error);}},onReject: (reason) => {try {const res = onReject(reason);this.resolvePromise(promise, res, resolve, reject);} catch (error) {reject(error);}},});break;//成功状态case MyPromise.FULFILLED://异步执行 替代微任务setTimeout(() => {try {const res = onFulfilled(this.value);this.resolvePromise(promise, res, resolve, reject);} catch (error) {reject(error);}});break;//失败状态case MyPromise.REJECTED://异步执行 替代微任务setTimeout(() => {try {const resErr = onReject(this.value);//这里注意 上一步的是reject状态 下一个链式then接收结果是resolve接收resolve(resErr);} catch (error) {reject(error);}});break;}});//返回一个promise实例return promise;}
4.实现类catch的方法
catch(onReject) {return this.then(undefined, onReject);}
5.实现类finally的方法
//成功和失败都会执行finally(callback) {return this.then((val) => {return MyPromise.resolve(callback()).then(() => val);},(reason) => {return MyPromise.resolve(callback()).then(() => reason);});}
6.实现类then核心代码复用逻辑resolvePromise
//then核心代码复用逻辑resolvePromise(p, res, resolve, reject) {//不能重复传入同一个Promiseif (p === res) throw new TypeError('Chaining cycle detected');try {// 返回结果是一个promise对象 那么直接调用thenif (res instanceof MyPromise) {res.then((val) => resolve(val),(reason) => reject(reason));} else {resolve(res);}} catch (error) {reject(error);}}
7.实现静态方法resolve
//静态resolve 返回一个promise 执行resolve方法static resolve(val) {return new MyPromise((resolve, reject) => {if (val instanceof MyPromise) {val.then(resolve, reject);} else {resolve(val);}});}
8.实现静态方法reject
//静态resolve 返回一个promise 执行reject方法static reject(reason) {return new MyPromise((resolve, reject) => {reject(reason);});}
9.静态all方法 数组所有promise都请求成功才返回resolve 有一个失败就直接reject返回
static all(promiseArr) {const values = [];return new MyPromise((resolve, reject) => {promiseArr.map((promise) => {promise.then((val) => {values.push(val);if (values.length === promiseArr.length) {resolve(values);}},(reason) => reject(reason));});});}
10.静态race方法 不管是resolve还是reject谁先调用就执行谁 只会执行第一个成功的
static race(promiseArr) {return new MyPromise((resolve, reject) => {promiseArr.map((promise) => {promise.then((val) => resolve(val),(reason) => reject(reason));});});}
结尾附上完整版代码,为了测试不和原生的Promise名字冲突,此处名字用MyPromise。
class MyPromise {static PENDING = 'pending';static FULFILLED = 'fulfilled';static REJECTED = 'rejected';constructor(executer) {//初始状态this.status = MyPromise.PENDING;//初始值this.value = null;//等待状态成功和失败函数暂时存放起来this.callbacks = [];//传入的函数 resolve 和 reject参数try {executer(this.resolve.bind(this), this.reject.bind(this));} catch (error) {this.reject.bind(this, error);}}resolve(val) {//只有pending状态才会改变if (this.status === MyPromise.PENDING) {this.status = MyPromise.FULFILLED;this.value = val;//多次触发then和异步处理方案setTimeout(() => {this.callbacks.map((callback) => {callback.onFulfilled(val);});});}}reject(reason) {//只有pending状态才会改变if (this.status === MyPromise.PENDING) {this.status = MyPromise.REJECTED;this.value = reason;//多次触发then和异步处理方案setTimeout(() => {this.callbacks.map((callback) => {callback.onReject(reason);});});}}then(onFulfilled = (val) => val,onReject = (reason) => {throw reason;}) {const promise = new MyPromise((resolve, reject) => {switch (this.status) {//等待状态case MyPromise.PENDING:this.callbacks.push({onFulfilled: (val) => {try {const res = onFulfilled(val);this.resolvePromise(promise, res, resolve, reject);} catch (error) {reject(error);}},onReject: (reason) => {try {const res = onReject(reason);this.resolvePromise(promise, res, resolve, reject);} catch (error) {reject(error);}},});break;//成功状态case MyPromise.FULFILLED://异步执行 替代微任务setTimeout(() => {try {const res = onFulfilled(this.value);this.resolvePromise(promise, res, resolve, reject);} catch (error) {reject(error);}});break;//失败状态case MyPromise.REJECTED://异步执行 替代微任务setTimeout(() => {try {const resErr = onReject(this.value);//这里注意 上一步的是reject状态 下一个链式then接收结果是resolve接收resolve(resErr);} catch (error) {reject(error);}});break;}});//返回一个promise实例return promise;}//返回失败的结果catch(onReject) {return this.then(undefined, onReject);}//成功和失败都会执行finally(callback) {return this.then((val) => {return MyPromise.resolve(callback()).then(() => val);},(reason) => {return MyPromise.resolve(callback()).then(() => reason);});}//then核心代码复用逻辑resolvePromise(p, res, resolve, reject) {//不能重复传入同一个Promiseif (p === res) throw new TypeError('Chaining cycle detected');try {// 返回结果是一个promise对象 那么直接调用thenif (res instanceof MyPromise) {res.then((val) => resolve(val),(reason) => reject(reason));} else {resolve(res);}} catch (error) {reject(error);}}//静态resolve 返回一个promise 执行resolve方法static resolve(val) {return new MyPromise((resolve, reject) => {if (val instanceof MyPromise) {val.then(resolve, reject);} else {resolve(val);}});}//静态resolve 返回一个promise 执行reject方法static reject(reason) {return new MyPromise((resolve, reject) => {reject(reason);});}/* Promise.all和Promise.race的实现原理:Promise.all 原理:当传入的数组每一个promise调用结果状态都是成功,那么返回一个数组包含入参返回值Promise.race 原理:当传入的数组每一个promise调用,返回值由最快改变状态的Promise决定*///静态all方法 数组所有promise都请求成功才返回resolve 有一个失败就直接reject返回static all(promiseArr) {const values = [];return new MyPromise((resolve, reject) => {promiseArr.map((promise) => {promise.then((val) => {values.push(val);if (values.length === promiseArr.length) {resolve(values);}},(reason) => reject(reason));});});}//静态race方法 不管是resolve还是reject谁先调用就执行谁 只会执行第一个成功的static race(promiseArr) {return new MyPromise((resolve, reject) => {promiseArr.map((promise) => {promise.then((val) => resolve(val),(reason) => reject(reason));});});}
}
实现Promise的resolve/reject/then/all/race/finally/catch方法相关推荐
- promise存在的意义分析resolve reject catch
简介 new Promise(function(resolve,reject){}); 状态 pending: 初始状态,成功或失败状态. fulfilled: 意味着操作成功完成.对应resolve ...
- Promise、THEN链的穿透/顺延机制、关于Promise.all/any/race 三个方法的研究、AJAX的串行和并行
文章目录 一.Promise 1.认识Promise Promise的实例肯能由三种状态: Promise原型上的方法: Promise的静态方法: then catch async await 练习 ...
- es6 Promise.prototype.catch()方法
Promise.prototype.catch()方法 Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数. getJ ...
- JavaScript系列之Promise的resolve、reject、then、catch
文章の目录 一.什么是Promise 二.Promise的优点 三.promise的三种状态 四.简单使用 1.Promise()构造器 1.1.概述 1.2.语法 1.3.参数 1.4.返回值 2. ...
- (基础)Promise的resolve参数
resolve参数有以下几种类型 传入普通的值或者对象 then里正常打印 new Promise((resolve, reject) => {resolve('普通值或对象') // 普通的值 ...
- Expected the Promise rejection reason to be an Error 的 解决方法
问题描述:使用 eslint 出现 Expected the Promise rejection reason to be an Error 的问题. handleGeocoder (address) ...
- Promise中的then第二个参数和catch的区别
Promise中的then第二个参数和catch有什么区别? 首页我们先要区分几个概念: reject是用来抛出异常的,catch是用来处理异常的: reject是Promise的方法,而then和c ...
- (基础)Promise中catch()方法使用,捕获错误(拒绝)
如果Promise抛出错误,then中没有处理就会报错 报错情况 // 这样会报错,因为没有处理promise的拒绝 const promise = new Promise((resolve, rej ...
- IDEA编译时出现“cannot resolve symbol“的问题时的解决方法。
IDEA编译时出现"cannot resolve symbol"的问题时的解决方法. 参考文章: (1)IDEA编译时出现"cannot resolve symbol&q ...
- Typescript实现Promise,[then|catch|finally|resolve|reject|race|all|any]
最新文章
- BERT大火却不懂Transformer?读这一篇就够了 重点 命名实体识别
- SmartGit安装及使用
- 双主数据库配置与应用
- MCMC笔记Metropilis-Hastings算法(MH算法)
- 深度学习核心技术精讲100篇(三十一)-大众点评搜索基于知识图谱的深度学习排序实践
- wxWidgets 编译 ICON 资源
- java三角形剪角_大班数学:拼角剪角
- HDU-2067-小兔的棋盘
- 大数据分析技术趋势有哪些
- 算法与数据结构实验题 4.1 伊姐姐数字 game
- 浅谈三种使用Redis实现MQ的方式
- 提供SCDN基础版本售卖
- linux批量修改文件后缀
- photoshop 插件_什么是Photoshop插件,扩展程序和附加组件?
- lomboz eclipse怎么连接oracle10,Lomboz插件的安装与配置[Eclipse 3.0,3.1.x与3.2.x版本]第一部分...
- 微信小程序实现倒计时功能(超简单)
- 关于CSDN如何搜索用户以及关注好友
- win10家庭版将中文用户名修改为英文
- 固态硬盘ssd的寿命如何计算,固态硬盘质量怎么检测?
- MIPI DSI之DBI DPI含义和区别(3-1)
热门文章
- AD再见--AdGuardHome神器
- ssm基于微信平台的牙科就诊信息管理系统的设计与实现 毕业设计源码211157
- jsp 图片下载功能
- 个人简历英语及计算机能力怎么写,简历个人能力怎么写(简历中个人能力的填写技巧)...
- 如何使用动态域名,并且自己来定时更新
- 【渝粤题库】陕西师范大学209020 史记研究 作业(专升本)
- css 实现一个尖角_css 实现一个带尖角的正方形
- 某市有甲、乙、丙、丁四个居民区,自来水有A,B,C三个水库供应
- 使用合取范式进行整数规划建模的方法
- 编程数学课:万万没想到,他们都用这个方式学好了数学