行业知识
【JavaScript】手写 Promise(静态方法)
2026-10-20 14:32:52
来源:互联网转载
手写Promise-静态方法resolve
需���:
- 返回一个带有成功原因的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)}) 核心步骤:
- 增加静态方法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
- 通过static关键字添加静态方法resolve,接收参数value
- 内部判断传入的值
- 如果是Promise实例,直接返回
- 其他的值,创建Promise实例并返回,内部通过resolve(value)传递value
手写Promise-静态方法reject
需求:
- 返回一个带有拒绝原因的Promise对象
HMPromise.reject('error').catch(res => { console.log(res)}) 核心步骤:
- 添加静态方法
- 返回rejected状态的Promise
static reject(value) { // 1. 返回rejected状态的Promise // new HMPromise((resolve,reject)=>{ return new HMPromise((undefined, reject) => { reject(value) }) } 面试回答
手写Promise-静态方法reject
- 添加静态方法reject并接收参数value
- 内部返回一个拒绝状态的Promise实例即可
手写Promise-静态方法race
需求:
- 接收Promise数组,数组中第一个Promise敲定时,获取成功/失败结果
- 传入的参数不是数组,直接报错
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)}) 核心步骤:
- 返回Promise
- 判断是否未数组,不是直接报错
- 等待第一个敲定
static race(promises) { // 1. 返回Promise return new HMPromise((resolve, reject) => { // 2. 判断是否为数组 if (!Array.isArray(promises)) { return reject(new TypeError('Argument is not iterable')) } // 3. 等待第一个敲定 promises.forEach(p => { // p.then HMPromise.resolve(p).then(res => { resolve(res) }, err => { reject(err) }) }) }) } 面试回答:
手写Promise-静态方法race
- 添加静态方法race接收参数promises
- 内部返回一个新的Promise实例,在返回的Promise实例中:
- 判断参数是否为数组,不是通过reject传递错误
- 遍历Promise数组,通过resolve静态方法等待每一个兑现
- 任何一个兑现,调用resolve传递兑现结果
- 任何一个拒绝,调用reject传递拒绝原因
手写Promise-静态方法all
需求:
- 接收Promise数组
- 所有Promise都成功时,返回一个成功的Promise对象及成功数组
- 任何一个Promise失败,返回一个失败的Promise对象及第一个失败原因
const p1 = HMPromise.resolve(1)const p2 = new HMPromise((resolve, reject) => { setTimeout(() => { resolve(2) // reject('error') }, 1000)})const p3 = 3HMPromise.all([p1, p2, p3]).then(res => { console.log('res:', res)}, err => { console.log('err:', err)}) 核心步骤:
- 返回Promise
- 判断参数是否未数组:
- 不是:直接报错
- 是:
- 空数组直接兑现
- 处理全部兑现:记录结果->判断全部兑现
- 处理第一个拒绝
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 = 0 promises.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
- 添加静态方法all
- 内部返回Promise实例,在返回的Promise实例中:
- 判断参数是否为数组,不是通过reject传递错误
- 空数组直接以空数组为结果进行兑现
- 遍历Promise数组,通过resolve静态方法等待结果
- 处理全部兑现:
- 通过数组记录结果,用索引的方式来添加,目的是保证结果的顺序和Promise数组的顺序一致
- 通过兑现次数进行判断,因为是通过索引的方式记录结果,如果第一次兑现的是最后一个,那么数组的长度就已经和Promise数组的长度一致了,所以需要通过兑现次数来进行判断
- 任意一个拒绝,调用reject传递拒绝原因
- 处理全部兑现:
手写Promise-静态方法allSettled
需求:-传送门
- 传入Promise数组,当所有对象都已敲定时
- 返回一个新的Promise对象及以数组形式保存的结果
const p1 = HMPromise.resolve(1)const p2 = 2const 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)}) 核心步骤:
- 返回Promise
- 判断是否为数组:
- 不是:报错
- 是:
- 空数组:直接兑现
- 等待全部敲定:并记录结果
- 处理兑现:{state:FULFILLED,value:'xxx'}
- 处理拒绝:{state:REJECTED,reason:'xxx'}
static allSettled(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. 等待全部敲定 // 4.1 记录结果 const results = [] let count = 0 promises.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方法类似,区别是要获取全部敲定的结果(成功/拒绝),以及获取的结果是对象形式
- 添加静态方法allSettled
- 内部返回Promise实例,在返回的Promise实例中:
- 判断参数是否为数组,不是通过reject传递错误
- 空数组直接以空数组为结果进行兑现
- 遍历Promise数组,通过resolve静态方法等待敲定结果
- 等待全部敲定:并记录结果,根据兑现和拒绝将如下格式的内容通过索引的方式的记录到数组中
- 处理兑现:{state:FULFILLED,value:'xxx'}
- 处理拒绝:{state:REJECTED,reason:'xxx'}
- 根据敲定的次数判断是否全部敲定,全部敲定之后,通过resolve传递结果数组
手写Promise-静态方法any
需求:-传送门
- 传入Promise数组,
- 任何一个Promise对象敲定时,返回一个新的Promise对象,及对应的结果
- 所有Promise都被拒绝时,返回一个包含所有拒绝原因的AggregateError错误数组
const p1 = new HMPromise((resolve, reject) => { setTimeout(() => { reject(1) }, 2000)})const p2 = 2const 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)}) 核心步骤:
- 返回Promise
- 判断是否为数组
- 不是:报错
- 是:
- 空数组:直接拒绝
- 等待结果:
- 第一个兑现
- 全部拒绝
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 = 0 promises.forEach((p, index) => { HMPromise.resolve(p).then(res => { // 3.1 第一个兑现 resolve(res) }, err => { // 3.2 全部拒绝 errors[index] = err count++ count === promises.length && reject(new AggregateError(errors, 'All promises were rejected')) }) }) }) } 面试回答:
手写Promise-静态方法any
做法和all方法也有点类似,区别是获取第一个兑现,或者是全部拒绝
- 添加静态方法any
- 内部返回Promise实例,在返回的Promise实例中:
- 判断参数是否为数组,不是通过reject传递错误
- 空数组直接以空数组为结果进行兑现
- 遍历Promise数组,通过resolve静态方法等待结果
- 第一个兑现,通过resolve传递兑现结果
- 全部拒绝:
- 定义数组,保存拒绝原因,通过索引记录,目的是保证顺序和Promise数组一致
- 通过次数判断是否全部拒绝,当全部拒绝时,通过reject传递AggregateError类型的错误,并将拒绝原因数组传递进去即可
上一篇:电脑建立服务器怎么建立?
下一篇:五百元主机