小工具知识网

当前位置: 首页 > 行业知识 > 【JavaScript】手写 Promise(静态方法)

行业知识

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

2026-10-20 14:32:52 来源:互联网转载

手写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. 返回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

  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 = 3HMPromise.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 = 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

  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 = 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)})

核心步骤:

  1. 返回Promise
  2. 判断是否为数组:
    1. 不是:报错
    2. 是:
      1. 空数组:直接兑现
      2. 等待全部敲定:并记录结果
        1. 处理兑现:{state:FULFILLED,value:'xxx'}
        2. 处理拒绝:{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方法类似,区别是要获取全部敲定的结果(成功/拒绝),以及获取的结果是对象形式

  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 = 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)})

核心步骤:

  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 = 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方法也有点类似,区别是获取第一个兑现,或者是全部拒绝

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

上一篇:电脑建立服务器怎么建立?

下一篇:五百元主机