【JavaScript】手写 Promise(静态方法)

手写Promise-静态方法resolve

需求:

  1. 返回一个带有成功原因的Promise对象
HMPromise.resolve(new HMPromise((resolve, reject) => {// resolve('resolve')// reject('reject')// throw 'error'
})).then(res => {console.log('res:', res)
}, err => {console.log('err:', err)
})
HMPromise.resolve('itheima').then(res => {console.log(res)
})

核心步骤:

  1. 增加静态方法resolve,根据传入的值返回不同的结果即可
  static resolve(value) {// 1. 判断传入值if (value instanceof HMPromise) {// 2.1 Promise直接返回return value}// 2.2 转为Promise并返回(fulfilled状态)// return new HMPromise((resolve, reject) => {return new HMPromise((resolve) => {resolve(value)})}
面试回答:

手写Promise-静态方法resolve

  1. 通过static关键字添加静态方法resolve,接收参数value
  2. 内部判断传入的值
    1. 如果是Promise实例,直接返回
    2. 其他的值,创建Promise实例并返回,内部通过resolve(value)传递value

手写Promise-静态方法reject

需求:

  1. 返回一个带有拒绝原因的Promise对象
HMPromise.reject('error').catch(res => {console.log(res)
})

核心步骤:

  1. 添加静态方法
  2. 返回rejected状态的Promise
  static reject(value) {// 1. 返回rejected状态的Promise// new HMPromise((resolve,reject)=>{return new HMPromise((undefined, reject) => {reject(value)})}
面试回答

手写Promise-静态方法reject

  1. 添加静态方法reject并接收参数value
  2. 内部返回一个拒绝状态的Promise实例即可

手写Promise-静态方法race

需求:

  1. 接收Promise数组,数组中第一个Promise敲定时,获取成功/失败结果
  2. 传入的参数不是数组,直接报错

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

const p1 = new HMPromise((resolve, reject) => {setTimeout(() => {resolve(1)}, 2000)
})
const p2 = new HMPromise((resolve, reject) => {setTimeout(() => {reject(2)}, 1000)
})
HMPromise.race([p1, p2, 'itheima']).then((res) => {console.log('res:', res)
}, err => {console.log('err:', err)
})

核心步骤:

  1. 返回Promise
  2. 判断是否未数组,不是直接报错
  3. 等待第一个敲定
  static race(promises) {// 1. 返回Promisereturn new HMPromise((resolve, reject) => {// 2. 判断是否为数组if (!Array.isArray(promises)) {return reject(new TypeError('Argument is not iterable'))}// 3. 等待第一个敲定promises.forEach(p => {// p.thenHMPromise.resolve(p).then(res => { resolve(res) }, err => { reject(err) })})})}
面试回答:

手写Promise-静态方法race

  1. 添加静态方法race接收参数promises
  2. 内部返回一个新的Promise实例,在返回的Promise实例中:
    1. 判断参数是否为数组,不是通过reject传递错误
    2. 遍历Promise数组,通过resolve静态方法等待每一个兑现
    3. 任何一个兑现,调用resolve传递兑现结果
    4. 任何一个拒绝,调用reject传递拒绝原因

手写Promise-静态方法all

需求:

  1. 接收Promise数组
    1. 所有Promise都成功时,返回一个成功的Promise对象及成功数组
    2. 任何一个Promise失败,返回一个失败的Promise对象及第一个失败原因
const p1 = HMPromise.resolve(1)
const p2 = new HMPromise((resolve, reject) => {setTimeout(() => {resolve(2)// reject('error')}, 1000)
})
const p3 = 3
HMPromise.all([p1, p2, p3]).then(res => {console.log('res:', res)
}, err => {console.log('err:', err)
})

核心步骤:

  1. 返回Promise
  2. 判断参数是否未数组:
    1. 不是:直接报错
  3. 是:
    1. 空数组直接兑现
  4. 处理全部兑现:记录结果->判断全部兑现
    1. 处理第一个拒绝
static all(promises) {// 1. 返回Promise实例return new HMPromise((resolve, reject) => {// 2. 判断是否为数组if (!Array.isArray(promises)) {return reject(new TypeError('Argument is not iterable'))}// 3. 空数组直接兑现promises.length === 0 && resolve(promises)// 4.1 记录结果const results = []let count = 0promises.forEach((p, index) => {HMPromise.resolve(p).then(res => {// results.push 无法保证 结果的顺序和Promise数组的顺序一致// index 和 Promise实例的索引一致,保证顺序results[index] = res// 4.2 判断全部兑现count++count === promises.length && resolve(results)}, err => {// 5. 处理第一个拒绝reject(err)})})})}
面试回答:

手写Promise-静态方法all

  1. 添加静态方法all
  2. 内部返回Promise实例,在返回的Promise实例中:
    1. 判断参数是否为数组,不是通过reject传递错误
    2. 空数组直接以空数组为结果进行兑现
    3. 遍历Promise数组,通过resolve静态方法等待结果
      1. 处理全部兑现:
        1. 通过数组记录结果,用索引的方式来添加,目的是保证结果的顺序和Promise数组的顺序一致
        2. 通过兑现次数进行判断,因为是通过索引的方式记录结果,如果第一次兑现的是最后一个,那么数组的长度就已经和Promise数组的长度一致了,所以需要通过兑现次数来进行判断
      2. 任意一个拒绝,调用reject传递拒绝原因

手写Promise-静态方法allSettled

需求:-传送门

  1. 传入Promise数组,当所有对象都已敲定时
  2. 返回一个新的Promise对象及以数组形式保存的结果
const p1 = HMPromise.resolve(1)
const p2 = 2
const p3 = new HMPromise((resolve, reject) => {setTimeout(() => {reject(3)}, 1000)
})
HMPromise.allSettled([p1, p2, p3]).then(res => {console.log('res:', res)
}, err => {console.log('err:', err)
})

核心步骤:

  1. 返回Promise
  2. 判断是否为数组:
    1. 不是:报错
    2. 是:
      1. 空数组:直接兑现
      2. 等待全部敲定:并记录结果
        1. 处理兑现:{state:FULFILLED,value:'xxx'}
        2. 处理拒绝:{state:REJECTED,reason:'xxx'}
  static allSettled(promises) {// 1. 返回Promisereturn new HMPromise((resolve, reject) => {// 2. 数组判断if (!Array.isArray(promises)) {return reject(new TypeError('Argument is not iterable'))}// 3. 为空直接敲定promises.length === 0 && resolve(promises)// 4. 等待全部敲定// 4.1 记录结果const results = []let count = 0promises.forEach((p, index) => {HMPromise.resolve(p).then(res => {// 4.2 处理兑现{status:'fulfilled',value:''}results[index] = { status: FULFILLED, value: res }count++count === promises.length && resolve(results)}, err => {// 4.3 处理拒绝{status:'rejected',reason:''}results[index] = { status: REJECTED, reason: err }count++count === promises.length && resolve(results)})})})}
面试回答:

手写Promise-静态方法allSettled

做法和all方法类似,区别是要获取全部敲定的结果(成功/拒绝),以及获取的结果是对象形式

  1. 添加静态方法allSettled
  2. 内部返回Promise实例,在返回的Promise实例中:
    1. 判断参数是否为数组,不是通过reject传递错误
    2. 空数组直接以空数组为结果进行兑现
  3. 遍历Promise数组,通过resolve静态方法等待敲定结果
  4. 等待全部敲定:并记录结果,根据兑现和拒绝将如下格式的内容通过索引的方式的记录到数组中
    1. 处理兑现:{state:FULFILLED,value:'xxx'}
    2. 处理拒绝:{state:REJECTED,reason:'xxx'}
  5. 根据敲定的次数判断是否全部敲定,全部敲定之后,通过resolve传递结果数组

手写Promise-静态方法any

需求:-传送门

  1. 传入Promise数组,
    1. 任何一个Promise对象敲定时,返回一个新的Promise对象,及对应的结果
    2. 所有Promise都被拒绝时,返回一个包含所有拒绝原因的AggregateError错误数组
const p1 = new HMPromise((resolve, reject) => {setTimeout(() => {reject(1)}, 2000)
})
const p2 = 2
const p3 = new HMPromise((resolve, reject) => {setTimeout(() => {resolve(3)// reject(3)}, 1000)
})
HMPromise.any([p1, p2, p3]).then(res => {console.log('res:', res)
}, err => {console.dir(err)
})

核心步骤:

  1. 返回Promise
  2. 判断是否为数组
    1. 不是:报错
    2. 是:
      1. 空数组:直接拒绝
      2. 等待结果:
        1. 第一个兑现
        2. 全部拒绝
  static any(promises) {// 1. 返回Promise,数组判断return new HMPromise((resolve, reject) => {if (!Array.isArray(promises)) {return reject(new TypeError('Argument is not iterable'))}// 2. 空数组直接拒绝promises.length === 0 && reject(new AggregateError(promises, 'All promises were rejected'))// 3. 等待结果const errors = []let count = 0promises.forEach((p, index) => {HMPromise.resolve(p).then(res => {// 3.1 第一个兑现resolve(res)}, err => {// 3.2 全部拒绝errors[index] = errcount++count === promises.length && reject(new AggregateError(errors, 'All promises were rejected'))})})})}
面试回答:

手写Promise-静态方法any

做法和all方法也有点类似,区别是获取第一个兑现,或者是全部拒绝

  1. 添加静态方法any
  2. 内部返回Promise实例,在返回的Promise实例中:
    1. 判断参数是否为数组,不是通过reject传递错误
    2. 空数组直接以空数组为结果进行兑现
  3. 遍历Promise数组,通过resolve静态方法等待结果
    1. 第一个兑现,通过resolve传递兑现结果
    2. 全部拒绝:
      1. 定义数组,保存拒绝原因,通过索引记录,目的是保证顺序和Promise数组一致
      2. 通过次数判断是否全部拒绝,当全部拒绝时,通过reject传递AggregateError类型的错误,并将拒绝原因数组传递进去即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/508347.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Google Dremel和parquet的复杂嵌套数据结构表征方法解析

转载请注明出处。作者:archimekai 核心参考文献: Dremel: Interactive Analysis of Web-Scale Datasets 文章目录 引言复杂嵌套数据结构的无损表征问题Dremel论文中提出的表征方法parquet备注 引言 Dremel是Google的交互式分析系统。Google大量采用prot…

阅读笔记 | Transformers in Time Series: A Survey

阅读论文: Wen, Qingsong, et al. “Transformers in time series: A survey.” arXiv preprint arXiv:2202.07125 (2022). 这篇综述主要对基于Transformer的时序建模方法进行介绍。论文首先简单介绍了Transformer的基本原理,包括位置编码、多头注意力机…

01 MySQL之连接

1. 连接 1.0 基础认知 多表(主表)和一表(从表的区别): 多表一般是主表,一般存储主要数据,每个字段都可能存在重复值,没有主键,无法根据某个字段定位到准确的记录; 一表一般是从表,一般存储辅助数据&…

基础二分学习笔记

模板 : 个人倾向第一种 ; 整数二分 : 最大化查找 : 可行区域在左侧 : 查找最后一个<q的数的下标 : int find(int q){// 查找最后一个 < q 的下标 int l 0 , r n 1 ;while(l 1 < r){int mid l r >> 1 ;if(a[mid]<q) l mid ;else r mid ;}return…

如何限制一个账号只在一处登陆

大家好&#xff0c;我是广漂程序员DevinRock&#xff01; 1. 需求分析 前阵子&#xff0c;和问答群里一个前端朋友&#xff0c;随便唠了唠。期间他问了我一个问题&#xff0c;让我印象深刻。 他问的是&#xff0c;限制同一账号只能在一处设备上登录&#xff0c;是如何实现的…

第二篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas金融数据分析

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas 在金融数据分析中的常见用途和功能介绍二、金融数据清洗和准备示例代码三、金融数据索引和选择示例代码四、金融数据时间序列分析示例代码五、金融数据可视化示例代码六、金融数…

CUDA 中的线程组织

明朝那些事中有一句话&#xff1a;我之所以写徐霞客是想告诉你&#xff0c;所谓千秋霸业万古流芳&#xff0c;与一件事相比&#xff0c;其实都算不了什么&#xff0c;这件事情就是——用你喜欢的方式度过一生。 我们以最简单的 CUDA 程序&#xff1a;从 GPU 中输出 Hello World…

C++基于多设计模式下的同步异步日志系统day4

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C基于多设计模式下的同步&异步日志系统 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 只要内容主要实现了同步日志消息…

Unreal触屏和鼠标控制旋转冲突问题

Unreal触屏和鼠标控制旋转冲突问题 鼠标控制摄像机旋转添加Input轴计算旋转角度通过轴事件控制旋转 问题和原因问题原因 解决办法增加触摸控制旋转代码触屏操作下屏蔽鼠标轴响应事件 鼠标控制摄像机旋转 通过Mouse X和Mouse Y控制摄像机旋转。 添加Input轴 计算旋转角度 通过…

外贸网站模板建站

测绘检测wordpress外贸主题 简洁实用的wordpress外贸主题&#xff0c;适合做测绘检测仪器设备的外贸公司使用。 https://www.jianzhanpress.com/?p5337 白马非马衣服WordPress外贸建站模板 白马非马服装行业wordpress外贸建站模板&#xff0c;适用于时间服装企业的官方网站…

利用redis实现秒杀功能

6、秒杀优化 这个是 图灵 的redis实战里面的一个案例 6.1 秒杀优化-异步秒杀思路 我们来回顾一下下单流程 当用户发起请求&#xff0c;此时会请求nginx&#xff0c;nginx会访问到tomcat&#xff0c;而tomcat中的程序&#xff0c;会进行串行操作&#xff0c;分成如下几个步骤…

求Sn=a+aa+aaa+aaaa+aaaaa的前n项之和

求Snaaaaaaaaaaaaaaa的前5项之和&#xff0c;其中a是一个数字&#xff0c; 例如&#xff1a;222222222222222 int main() {int a;scanf("%d", &a);int n;scanf("%d", &n);int sum 0;int tmp 0;for (int i 0; i < n; i){tmp tmp * 10 a;sum…