IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 手写Promise -> 正文阅读

[JavaScript知识库]手写Promise

先说一下大致的思路,可能并不是按照这么个顺序,我也是模仿Promise的基本使用,就想起来啥总结啥,我觉得应是把 Promise 核心的部分写出来了。

?1. 创建MyPromise类

?2. 实例化时传入一个函数fn,并立即执行

?3. fn有两个形参(resolve和reject),并且都是函数

?4. 声明Promise的三个状态分别是 pending、fulfilled、rejected,并在实例化的时候赋予初始pending状态

?5. 调用resolve和reject的时候 改变其状态,调用then方法,并将数据传递过去。实例化时给Promise一个初始数据result = null

?6. then方法中的形参都是异步调用,resolve和reject也都是最后执行,所以采用 setTimeout

?7. 示例化的时候 如果出现错误或抛出异常,应该进行对异常捕获 调用reject方法,所以实例化立即执行的时候 采用 try catch

?8. then 方法的两个形参都必须是函数,如果传入的不是函数咱们就给其一个空函数

?9. 如果resolve也是个异步,这样的话,执行then方法的时候,判断状态还是pending,这时候就要分别向两个数组中 暂存then中两个的方法,在调用resolve的时候再去遍历调用。就是个发布订阅

10. then方法可以链式调用,所以我们在then方法中再返回一个手写的 MyPromise 即可

下面是代码:

class MyPromise {
  static PENDING = 'pending'
  static FULFILLED = 'fulfilled'
  static REJECTED = 'rejected'
  constructor(fn) {
    this.status = MyPromise.PENDING
    this.result = null
    this.resolveCallbacks = []
    this.rejectCallbacks = []
    try {
      fn(this.resolve.bind(this), this.reject.bind(this))
    }catch(err) {
      this.reject(err)
    }
  }
  resolve(data) {
    setTimeout(() => {
      if(this.status == MyPromise.PENDING) {
        this.status = MyPromise.FULFILLED
        this.result = data
        if(this.resolveCallbacks.length) {
          this.resolveCallbacks.forEach(callback => {
            callback(data)
          })
        }
      }
    })
  }
  reject(err) {
    setTimeout(() => {
      if(this.status == MyPromise.PENDING) {
        this.status = MyPromise.REJECTED
        this.result = err
        if(this.rejectCallbacks.length) {
          this.rejectCallbacks.forEach(callback => {
            callback(err)
          })
        }
      }
    })
  }
  then(ONFULFILLED, ONREJECTED) {
    return new MyPromise((resolve, reject) => {
      ONFULFILLED = typeof ONFULFILLED === 'function' ? ONFULFILLED : () => {}
      ONREJECTED = typeof ONREJECTED === 'function' ? ONREJECTED : () => {}
      if(this.status == MyPromise.PENDING) {
        this.resolveCallbacks.push(ONFULFILLED)
        this.rejectCallbacks.push(ONREJECTED)
      }
      if(this.status == MyPromise.FULFILLED) {
        setTimeout(() => {
          ONFULFILLED(this.result)
        })
      }
      if(this.status == MyPromise.REJECTED) {
        setTimeout(() => {
          ONREJECTED(this.result)
        })
      }
    })
  }
}

简单测试?

console.log('111111')
new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('resolve')
    // reject('reject')
    console.log('哈哈哈')
  })
}).then(data => {
  console.log(data)
}, err => {
  console.log(err)
})
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:20:07  更:2022-02-28 15:22:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:19:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码