LogoLogo
github
  • 💪Upupup
  • React
    • hook
    • redux
    • Router
    • umimax+nest.js 实现 权限管理系统
    • umimax + Nest.js 实现权限管理系统
  • Vue
    • effectScope 是干啥的
    • Object.assign()
    • 响应式理解
    • @babel/preset-env 问题
    • 自定义指令
    • 问题及解决
    • 🧐权限管理(动态路由)
  • docker
    • Docker 常用命令
    • Docker部署遇到的问题
    • Docker Compose 常用命令
    • docker修改daemon.json
    • jenkins
    • Jenkinsfile 语法进阶
    • nginx配置
    • 问题
    • 玩转Nginx:轻松为Docker部署的服务添加域名的完美指南
    • Docker部署前后端项目:经验分享与问题解决
  • git
    • command
    • problem
    • rebase实践
  • 前端开发面试题集
    • CSS 面试题
    • 前端工程化面试题
    • HTML 面试题
    • JavaScript 面试题
    • NestJS 面试题
    • Node.js 面试题
    • 性能优化面试题
    • React 面试题
    • 安全面试题
    • Vue 面试题
  • interviewer
    • 计算机网络
    • 性能优化
  • leetcode
    • 算法
      • 分治算法
      • 滑动窗口与双指针
        • 🦸定长滑动窗口
        • 🚴不定长滑动窗口
        • 🚴‍♂️单序列双指针
      • 回溯
      • 二分法
  • nestjs
    • mail
    • mini-order
    • nestjs
    • prisma
    • 登录注册
  • nextjs
    • 用 V0 和 Cursor 实现全栈开发:从小白到高手的蜕变
  • tauri
    • 思路
    • 自动通知应用升级
  • vite
    • vite实现原理
  • webpack
    • 资料
  • 工具
    • Eslint
    • jenkins
    • 关于cicd
  • 微信小程序
    • ScoreDeck
    • h5跳转小程序问题
  • 思路
    • carTool
  • 操作系统学习
    • Linux命令
    • 计算机是如何计数的
    • nginx
      • location
      • try_files
  • 浏览器
    • session、location
    • web crypto
    • 性能监控和错误收集与上报
    • 预请求
  • 知识点整理
    • 知识点整理
  • 面试
    • Promise
    • 备战
    • 数码3
    • 腾娱
    • 腾讯云智
    • 重复请求合并
  • 前端工程化
    • 在 pnpm Monorepo 中使用公共方法包
由 GitBook 提供支持
在本页

这有帮助吗?

在GitHub上编辑
  1. 面试

Promise

function Promise(executor) {
  this.status = 'pending'
  this.value = null
  this.reason = null
  this.onFulfilledArray = []
  this.onRejectedArray = []

  const resolve = value => {
    if (value instanceof Promise) {
      return value.then(resolve, reject)
    }
    setTimeout(() => {
      if (this.status === 'pending') {
        this.value = value
        this.status = 'fulfilled'

        this.onFulfilledArray.forEach(func => {
          func(value)
        })
      }
    })
  }

  const reject = reason => {
    setTimeout(() => {
      if (this.status === 'pending') {
        this.reason = reason
        this.status = 'rejected'

        this.onRejectedArray.forEach(func => {
          func(reason)
        })
      }
    })
  }
    try {
        executor(resolve, reject)
    } catch(e) {
        reject(e)
    }
}

const resolvePromise = (promise2, result, resolve, reject) => {
  // 当 result 和 promise2 相等时,也就是说 onfulfilled 返回 promise2 时,进行 reject
  if (result === promise2) {
    return reject(new TypeError('error due to circular reference'))
  }

  // 是否已经执行过 onfulfilled 或者 onrejected
  let consumed = false
  let thenable

  if (result instanceof Promise) {
    if (result.status === 'pending') {
      result.then(function(data) {
        resolvePromise(promise2, data, resolve, reject)
      }, reject)
    } else {
      result.then(resolve, reject)
    }
    return
  }

  let isComplexResult = target => (typeof target === 'function' || typeof target === 'object') && (target !== null)
  // 如果返回的是疑似 Promise 类型
  if (isComplexResult(result)) {
    try {
      thenable = result.then
      // 如果返回的是 Promise 类型,具有 then 方法
      if (typeof thenable === 'function') {
        thenable.call(result, function(data) {
          if (consumed) {
            return
          }
          consumed = true

          return resolvePromise(promise2, data, resolve, reject)
        }, function(error) {
          if (consumed) {
            return
          }
          consumed = true

          return reject(error)
        })
      }
      else {
        return resolve(result)
      }

    } catch(e) {
      if (consumed) {
        return
      }
      consumed = true
      return reject(e)
    }
  }
  else {
    return resolve(result)
  }
}

Promise.prototype.then = function(onfulfilled, onrejected) {
  onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : data => data
  onrejected = typeof onrejected === 'function' ? onrejected : error => {throw error}

  // promise2 将作为 then 方法的返回值
  let promise2

  if (this.status === 'fulfilled') {
    return promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          // 这个新的 promise2 resolved 的值为 onfulfilled 的执行结果
          let result = onfulfilled(this.value)
          resolvePromise(promise2, result, resolve, reject)
        }
        catch(e) {
          reject(e)
        }
      })
    })
  }
  if (this.status === 'rejected') {
    return promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          // 这个新的 promise2 reject 的值为 onrejected 的执行结果
         let result = onrejected(this.reason)
         resolvePromise(promise2, result, resolve, reject)
        }
        catch(e) {
          reject(e)
        }
      })
    })
  }
  if (this.status === 'pending') {
    return promise2 = new Promise((resolve, reject) => {
      this.onFulfilledArray.push(value => {
        try {
          let result = onfulfilled(value)
          resolvePromise(promise2, result, resolve, reject)
        }
        catch(e) {
          return reject(e)
        }
      })

      this.onRejectedArray.push(reason => {
        try {
          let result = onrejected(reason)
          resolvePromise(promise2, result, resolve, reject)
        }
        catch(e) {
          return reject(e)
        }
      })      
    })
  }
}

Promise.prototype.catch = function(catchFunc) {
  return this.then(null, catchFunc)
}

Promise.resolve = function(value) {
  return new Promise((resolve, reject) => {
    resolve(value)
  })
}

Promise.reject = function(value) {
  return new Promise((resolve, reject) => {
    reject(value)
  })
}

Promise.race = function(promiseArray) {
  if (!Array.isArray(promiseArray)) {
      throw new TypeError('The arguments should be an array!')
  }
  return new Promise((resolve, reject) => {
    try {
      const length = promiseArray.length
      for (let i = 0; i <length; i++) {
        promiseArray[i].then(resolve, reject)
      }
    }
    catch(e) {
      reject(e)
    }
  })
}

Promise.all = function(promiseArray) {
  if (!Array.isArray(promiseArray)) {
      throw new TypeError('The arguments should be an array!')
  }
  return new Promise((resolve, reject) => {
    try {
      let resultArray = []

      const length = promiseArray.length

      for (let i = 0; i <length; i++) {
        promiseArray[i].then(data => {
          resultArray.push(data)

          if (resultArray.length === length) {
            resolve(resultArray)
          }
        }, reject)
      }
    }
    catch(e) {
      reject(e)
    }
  })
}
上一页面试下一页备战

最后更新于5个月前

这有帮助吗?