手写promise

简介: 手写promise

基本结构

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <script>
        class MyPromise {
            PromiseState = 'pending'
            PromiseResult = undefined
            constructor(executor) {
                // this指向将来new的实例对象
                //executor(函数1,函数2)
                try {
                    executor(this.resolve, this.reject)
                } catch (error) {
                    this.reject(error)
                }
 
            }
            //成功方法
            resolve = (val) => {
                if (this.PromiseState !== 'pending') return
                //成功状态
                this.PromiseState = 'fulfilled'
                //保存结果
                this.PromiseResult = val
            }
            //失败方法
            reject = (val) => {
                if (this.PromiseState !== 'pending') return
                //失败状态
                this.PromiseState = 'rejected'
                //保存结果
                this.PromiseResult = val
            }
 
        }
    </script>
//对比
    <script>
        let promise = new Promise((resolve, reject) => {
            //状态/结果
            // console.log('i love you ')
            resolve(100)
            // reject(100)
            // throw 400
        })
        console.log(promise)
    </script>
 
</body>
 
</html>
 
​//Promise的状态由
1.resolve
2.reject
3.throw
决定

在 JavaScript 中通过 queueMicrotask() 使用微任务 - Web API 接口参考 | MDN (mozilla.org)

<!DOCTYPE html>
<html lang="en">
 
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
 
<body>
  <script>
    class MyPromise {
      PromiseState = 'pending'
      PromiseResult = undefined
      //暂存两个回调,因为在调用时,可能有多个成功,失败的调用,then链式调用
      FulfilledCbs = []
      RejectedCbs = []
      constructor(executor) {
        // this指向将来new的实例对象
        //executor(函数1,函数2)
        try {
          executor(this.resolve, this.reject)
        } catch (error) {
          this.reject(error)
        }
 
      }
      //成功方法
      resolve = (val) => {
        if (this.PromiseState !== 'pending') return
        //成功状态
        this.PromiseState = 'fulfilled'
        //保存结果
        this.PromiseResult = val
        while (this.RejectedCbs.length) {
          //shift弹出来,length减1,0时while循环就结束了,没弹出执行后面加个括号shift()()
          this.RejectedCbs.shift()()
        }
      }
      //失败方法
      reject = (val) => {
        if (this.PromiseState !== 'pending') return
        //失败状态
        this.PromiseState = 'rejected'
        //保存结果
        this.PromiseResult = val
        while (this.FulfilledCbs.length) {
          //shift弹出来,length减1,0时while循环就结束了,没弹出执行后面加个括号shift()()
          this.FulfilledCbs.shift()()
        }
      }
      //接收两个回调
      // 如果当前promise对象为fulfilled 状态,执行回调一
      // 如果当前promise对象为rejected  状态,执行回调二
      // 如果当前promise对象为pending(待定) 状态,暂存两个回调
      //then 方法会返回新的promise对象,该对象的状态+结果由返回值决定
      /*返回值是promise 
      返回值为成功,新promise就是成功
      返回值为失败,新promise就是失败
          返回值非promise
      新promise就是成功,返回值就是返回值  
      */
      then(onFulfilled, onRejected) {
        //判断是否是函数,不是变成函数                                  val代表接收的promise=》原路返回
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
        // 函数保持失败状态
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
        // thenPromise新promise
        let thenPromise = new MyPromise((resolve, reject) => {
          const resolvePromise = (cb) => {
            queueMicrotask(() => {
              try {
                //把当前promise对象的值传入,进而使用
                let x = cb(this.PromiseResult)
                //如果是MyPromise对象\
                if (x === thenPromise) {
                  throw Error('不能返回自身')
                }
                if (x instanceof MyPromise) {
                  x.then(resolve, reject)
                } else {
                  resolve(x)
                }
 
              } catch (error) {
                reject(error)
              }
 
            })
          }
          if (this.PromiseState === 'fulfilled') {
 
            resolvePromise(onFulfilled)
          } else if (this.PromiseState === 'rejected') {
 
            resolvePromise(onRejected)
          } else if (this.PromiseState === 'pending') {
            //成功
            //将来调用时,把当前promise对象的值传入,进而使用
            this.FulfilledCbs.push(() => resolvePromise(this.onFulfilled))
            //失败
            this.RejectedCbs.push(() => resolvePromise(this.onRejected))
          }
 
        })
        return thenPromise
 
      }
 
      /*Promise.all()是个静态方法,参数是个数组
      返回一个promise
      数组中,所有promise对象都为成功,就返回成功状态
      数组中,只要有一个失败,就返回失败状态
      */
      static all(arr) {
        const result = []
        let n = 0
        return new Promise((resolve, reject) => {
          const addData = (index, val) => {
            result[index] = val
            n++
            if (n === arr.length) {
              resolve(result)
            }
          }
          arr.forEach((item, index) => {
            //判断是否是promise对象
            if (item instanceof MyPromise) {
              //resolve
              item.then(val => addData(index, val), reject)
            } else {
              addData(index, item)
            }
          })
        })
      }
 
      /* 
      race是静态方法
      返回一个promise
     数组中的字面量都视为成功的promise
     promise的状态+结果由参数数组中最快得到的结果决定
      */
      static race(val) {
        return new MyPromise((resolve, reject) => {
          arr.forEach(item => {
            if (item instanceof MyPromise) {
              item.then(resolve, reject)
            } else {
              //then是异步,为保证顺序,resolve(item)放到异步里
              queueMicrotask(() => {
                resolve(item)
              })
 
            }
          })
        })
      }
      /* 
      resolve是静态方法
      返回一个promise
      参数是promise对象,就原封不动返回该对象
      参数非promise对象,就返回一个成功的promise对象
      */
     
      /* 
      finally
      */
      finally(callback){
        return this.then(callback,callback).then(()=>this)
        
      }
      static resolve(val) {
        if (val instanceof MyPromise) return val
        return new MyPromise(resolve => resolve(val))
      }
      /* 
   reject是静态方法
   返回一个promise
   不管是什么,都会包裹为失败的promise对象,值PromiseResult就是传递的值
   */
      static reject(val) {
        return new MyPromise(_, reject(val => reject(val)))
      }
 
      /* 
      catch
      */
      catch(onRejected) {
        return this.then(_, onRejected)
      }
 
    }
    let my = new MyPromise()
    console.log(my)
  </script>
 
</body>
 
</html>
目录
相关文章
|
API 开发者
微信native支付对接案例详解
本文详细介绍了微信Native支付的对接流程,包括效果展示、产品介绍、接入前准备、开发指引、API列表、支付通知等,并强调了只有通过微信认证的服务号才能对接微信支付。每年需支付300元认证费用。
472 3
|
Web App开发 JavaScript 前端开发
2024年纯前端VUE在线编辑微软Office/金山WPS的Word/Excel文档
现在,随着数字化进程渗透到到各行各业,数据安全已经成为了数字化革命中的重要组成部分,而在线Office成在OA、ERP、文档系统中得到了广泛的应用,为我国的信息化事业也做出了巨大贡献。随着操作系统、浏览器及Office软件的不断升级和更新换代,加上国家对信息化、数字化系统要求的不断提升,一些厂家的WebOffice控件产品不断被淘汰出局,而现存的几个产品也存在以下几个问题:
1407 92
2024年纯前端VUE在线编辑微软Office/金山WPS的Word/Excel文档
微信小程序实现上传视频 / 上传图片功能以及整合上传视频 / 上传图片功能(超详细)
微信小程序实现上传视频 / 上传图片功能以及整合上传视频 / 上传图片功能(超详细)
|
人工智能 JavaScript 开发工具
【完全免费】VS Code 最好用的 12 款 AI 代码提示插件!!!
🎉 探索12款免费VSCode AI代码提示插件:Codeium、Codegeex、CodeFuse、TONGYI Lingma、Comate、iFlyCode、Fitten Code、Bito AI、Mintlify Doc Writer、Kodezi AI、aiXcoder、IntelliCode。这些插件提供智能补全、代码生成、注释、优化,支持多种语言,提升编程效率!🚀👩‍💻👨‍💻
18713 0
|
JavaScript
Vue中created与mounted的区别
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。 mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
1143 0
Vue中created与mounted的区别
|
8天前
|
云安全 监控 安全
|
13天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1391 8