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

手写Promise的静态方法

最近对promise原理的理解,手写下其中的静态方法。

手写Promise的静态方法

  • 1. Promise.resolve
  • 2. Promise.reject
  • 3. Promise.all
  • 4. Promise.any
  • 5. Promise.race
  • 6. Promise.allSettled

1. Promise.resolve

首先就是resolve方法,它会接收一个值,总是会将其转换为一个状态为fulfilled的Promise对象,如果传入的值本身就是Promise对象,那就直接返回。

了解原理代码便呼之欲出了:

Promise.resolve = function (value) {if (value instanceof Promise) {return value; // 当传入的是一个Promise对象时,直接返回}return new Promise(resolve => resolve(value)) // 否则返回一个状态为fulfilled的Promise
}

先对传入的value进行类型判断,使用instance of进行判断。instance of是通过原型链进行类型判断的,所以当value是Promise对象时,就会得到true,直接返回value即可;如果value不是Promise对象,那就返回一个新的Promise对象并且使用resolve包裹一下,就行了。

2. Promise.reject

reject方法就是与resolve方法相反的,总是会得到一个状态为rejected的promise对象,不一样的是,不管传入的value是什么,都返回一个状态为rejected的promise对象:

Promise.reject = function (value) {// 不管传入的是什么,直接返回一个状态为rejected的promisereturn new Promise((resolve, reject) => reject(value)) 
}

3. Promise.all

然后是all方法。
all方法会接收一个由Promise对象组成的数组,如果数组中的Promise对象状态都是fufilled,返回一个由这些Promise对象的值组成的新的状态为fufilled的promise;只要有一个失败就立即失败,返回一个状态为rejected的Promise,值为第一个失败的promise对象的值。
了解了原理,我们就来手写代码:

Promise.all = function (PromiseArr) {let i = 0, result = [] // i用来记录PromiseArr中成功的promise对象,result用来保存promise对象的值return new Promise((resolve, reject) => { // all方法会返回一个新的promise对象})
}

我们会使用一个i来记录PromiseArr中成功的promise对象个数,每成功一个i就加一,便把这个promise对象的值存放到result数组中。然后all最后一定会返回一个新的Promise,于是我们return new Promise。

Promise.all = function (PromiseArr) {let i = 0, result = [] // i用来记录PromiseArr中成功的promise对象,result用来保存promise对象的值return new Promise((resolve, reject) => { // all方法会返回一个新的promise对象PromiseArr.forEach((item, index) => { // 遍历传入的promise对象数组Promise.resolve(item)})})
}

然后我们遍历传入的PromiseArr数组,使用resolve方法将PromiseArr数组中的每个元素都转换为promise。如果item是promise,resolve方法会直接返回它;如果不是,返回一个promise对象。
于是,我们就可以在后面接then了:

Promise.all = function (PromiseArr) {let i = 0, result = [] // i用来记录PromiseArr中成功的promise对象,result用来保存promise对象的值return new Promise((resolve, reject) => { // all方法会返回一个新的promise对象PromiseArr.forEach((item, index) => { // 遍历传入的promise对象数组Promise.resolve(item).then(val => { // 利用resolve方法将promise数组中的元素都变为promisei++ // 每成功一个就加1result[index] = val // 按索引记录值if (i === PromiseArr.length) { // 当index等于promise数组长度时,说明全部成功,直接resolveresolve(result)}},err => {reject(err) // 只要有一个失败,立即失败})})})
}

当item状态是fufilled时,i就加一,并根据索引将item的值存放到result中,最后当i的值等于PromiseArr数组的长度时,说明PromiseArr数组每个promise都成功了,就resolve这个result数组;否则,只要有一个失败,就立即reject。
这样,一个基本的all方法我们就实现了。

4. Promise.any

any方法和all方法比较类似。any方法是当传入的promise数组每个状态都为rejected时返回一个状态为rejected的新Promise;否则,只要有一个状态为fufilled,就立即成功,返回第一个是 fulfilled 的新实例。

Promise.any = function (PromiseArr) {let i = 0 // 用来记录PromiseArr中失败的个数return new Promise((resolve, reject) => { // any方法会返回一个新的promise对象})
}

开头和all方法比较类似,我们使用一个i来记录PromiseArr数组中失败的个数,然后any方法会返回一个新的promise对象,于是我们就return new Promise。

Promise.any = function (PromiseArr) {let i = 0 // 用来记录PromiseArr中失败的个数return new Promise((resolve, reject) => { // any方法会返回一个新的promise对象PromiseArr.forEach((item, index) => { // 遍历PromiseArr数组Promise.resolve(item)})})
}

同样,我们使用resolve方法将数组中的每一项item都转化为promise对象。

Promise.any = function (PromiseArr) {let i = 0 // 用来记录PromiseArr中失败的个数return new Promise((resolve, reject) => { // any方法会返回一个新的promise对象PromiseArr.forEach((item, index) => { // 遍历PromiseArr数组Promise.resolve(item).then(val => { // 利用resolve方法将PromiseArr数组中的每个元素都变为promise对象resolve(val) // 只要有一个成功,立即成功},err => {i++ // 记录失败的次数if (i === PromiseArr.length) { // 当数组中全部失败时reject(new AggregateError('All promises were rejected'))}})})})
}

然后,每失败一次,i就加1。最后,当i等于PromiseArr数组的长度时,说明全部失败,就reject,值为 AggregateError 的错误;否则,只要有一个成功,立即成功。

这样,我们就实现了一个基本的any方法。

5. Promise.race

我们紧接着来手写一下race方法,race方法的原理是会返回第一个得出状态的promise的值,无论成功还是失败。

原理很简单,代码也比较简单:

Promise.race = function (PromiseArr) {return new Promise((resolve, reject) => {  // race方法会返回一个新的promise对象PromiseArr.forEach((item, index) => { // 遍历处理PromiseArr中元素Promise.resolve(item).then(val => {resolve(val) // 返回第一个成功的},err => {reject(err) // 或者第一个失败的})})})
}

6. Promise.allSettled

我们来手写一下今天的最后一个静态方法,也是比较复杂的一个,allSettled。
它主要是用来观察一组promise对象数组发生的变化,所有 Promise 的状态都变化了,那么新返回一个状态是 fulfilled 的 Promise,且它的值是一个数组,数组的每项由所有 Promise 的值和状态组成的对象;

Promise.allSettled = function (PromiseArr) {let result = []return new Promise((resolve, reject) => {})
}

我们使用result数组来保存最后的结果,allSettled方法也会返回一个新的promise对象,于是我们return new Promise。

Promise.allSettled = function (PromiseArr) {let result = []return new Promise((resolve, reject) => {PromiseArr.forEach((item, index) => {Promise.resolve(item)})})
}

同样,使用resolve方法将数组的每一项转换为promise对象。

Promise.allSettled = function (PromiseArr) {let result = []return new Promise((resolve, reject) => {PromiseArr.forEach((item, index) => {Promise.resolve(item).then(val => {result.push({status: 'fulfilled',value: val,})if (result.length === PromiseArr.length) {resolve(result)}},err => {result.push({status: 'rejected',reason: err,})if (result.length === PromiseArr.length) {resolve(result)}})})})
}

我们将每一个item的值都存入到result数组中,并且要记录每个item的状态,allSettled总是返回一个状态为fufilled的新promise,最后,当result的长度等于PromiseArr的长度,说明处理完毕,直接resolve这个result数组。
这样,我们也实现了一个基本的allSettled方法。

http://www.xdnf.cn/news/344683.html

相关文章:

  • Memgraph 的安装教程
  • 从一城一云到AI CITY,智慧城市进入新阶段
  • Oracle数据库DBF文件收缩
  • 基于大型语言模型的高效时间序列预测模型选择
  • 语音合成之十二 TTS声学编解码器的演进
  • 探索 C++23 的 views::cartesian_product
  • 【AI】DeepWiki 页面转换成 Markdown 保存 - Chrome 扩展
  • 可视化图解算法35:在二叉树中找到两个节点的最近公共祖先(二叉树的最近公共祖先)
  • 基于STM32、HAL库的FT231XS USB转UART收发器 驱动程序设计
  • 在Fiddler中添加自定义HTTP方法列并高亮显示
  • 姚琛全新特别版EP上线 携手金牌制作人诠释夏日浪漫
  • easyexcel导出动态写入标题和数据
  • 高频交直流传感技术在射频器件与微系统测试中的创新实践
  • TCP/IP和OSI对比
  • 【微信小程序开发】从0开始的一点点小记录
  • 并发与并行的关系
  • Java高频面试之并发编程-14
  • vue v-html无法解析<
  • 负载均衡算法解析(一)NGINX
  • 闪回查询和闪回表
  • es 里的Filesystem Cache 理解
  • [工具分享]欧拉角-四元数可视化工具
  • 科技成果鉴定测试有哪些内容?又有什么作用?
  • 美信监控易:网络设备智能识别与运维系统快捷配置
  • PostgreSQL 的 pg_current_logfile 函数
  • 利用session在html和MySQL实现登录
  • MySQL 8.0 OCP认证考试题库持续更新
  • 树状数组的操作问题--Python
  • SSL证书管理系统GO中文版自动申请SSL证书部署自动续期域名列表授权管理源码
  • 亚马逊推出新型仓储机器人 Vulcan:具备“触觉”但不会取代人类工人