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的理解及实现

基于回调的异步解决方案缺陷

js通常采用四种异步解决方案:回调、promise、Generator、async/await

  • 回调解决方案

通常异步的操作需要放入回调中进行执行,若要执行串行异步,则容易造成回调嵌套

  • promise优势
    • 通过then来实现异步的执行,解决了回调嵌套问题(本质 依然是回调)
    • 解决异步并发问题(promise.all)
    • 使错误处理变得简单

promise实现

  • 初步实现思路

    • 基本状态实现
    • 添加then
    • 显示异步操作
    const PENDING =  "PENDING"
      const REJECTED = "REJECTED"
      const FULFILLED =  "FULFILLED"
    
      class Promise{
          constructor(exector){
              this.status = PENDING
              this.value = null
              this.reason = null
              this.onResolveCallback = []
              this.onRejectedCallback =  []
              const resolve = (value)=>{
                  if(this.status===PENDING){
                      this.status = FULFILLED
                      this.value = value
                      this.onResolveCallback.forEach(fn=>fn())
                  }
              }
              const reject =(reason) => {
                  if(this.status === PENDING){
                      this.status = REJECTED
                      this.reason = reason
                      this.onRejectedCallback.forEach(fn=>fn())
                  }
              }
              try{
                  exector(resolve,reject)
              }catch(e){
                  reject(e)
              }
          }
    
          then(onFulfulled,onRejected){
              if(this.status === FULFILLED){
                  onFulfulled(this.value)
              }
              if(this.status === REJECTED){
                  onRejected(this.reason)
              }
              if(this.status === PENDING){
                  this.onResolveCallback.push(()=>{
                      onFulfulled(this.value)
                  })
                  this.onRejectedCallback.push(()=>{
                      onRejected(this.reason)
                  })
              }
          }
      }
    
      module.exports = Promise
    
  • 实现then的流程

    • then返回一个promise
    • then可以实现值的穿透
    const PENDING =  "PENDING"
      const REJECTED = "REJECTED"
      const FULFILLED =  "FULFILLED"
    
      function resolvePromise(promise2,x,resolve,reject){
          if(promise2 === x){
              return reject(new TypeError(`Chaining cycle detected for promise #<Promise> my`))
          }
          if((typeof x === 'object' && x!==null) || (typeof x === 'function')){
              let called = false
              try{
                  let then = x.then
                  if(typeof then  === 'function'){
                      then.call(x,y=>{
                          if(called)return
                          called = true
                          resolvePromise(promise2,y,resolve,reject)
                      },e=>{
                          if(called)return
                          called = true
                          reject(e)
                      })
                  }
                  else {
                      resolve(x)
                  }
              }catch(e){
                  if(called)return
                  called = true
                  reject(e)
              }
          }else {
              resolve(x)
          }
      }
    
      class Promise{
          constructor(exector){
              this.status = PENDING
              this.value = null
              this.reason = null
              this.onResolveCallback = []
              this.onRejectedCallback =  []
              const resolve = (value)=>{
                  if(value instanceof Promise){
                      return value.then(resolve,reject)
                  }
                  if(this.status===PENDING){
                      this.status = FULFILLED
                      this.value = value
                      this.onResolveCallback.forEach(fn=>fn())
                  }
              }
              const reject =(reason) => {
                  if(this.status === PENDING){
                      this.status = REJECTED
                      this.reason = reason
                      this.onRejectedCallback.forEach(fn=>fn())
                  }
              }
              try{
                  exector(resolve,reject)
              }catch(e){
                  reject(e)
              }
          }
    
          then(onFulfulled,onRejected){
              onFulfulled = typeof onFulfulled === 'function'?onFulfulled:v=>v
              onRejected = typeof onRejected === 'function'? onRejected:r=>{throw r}
              let promise2 = new Promise((resolve,reject)=>{
                  if(this.status === FULFILLED){
                      setTimeout(()=>{
                          try{
                              let x = onFulfulled(this.value)
                              resolvePromise(promise2,x,resolve,reject)
                          }
                          catch(e){
                              reject(e)
                          }
                      })
                  }
                  if(this.status === REJECTED){
                      setTimeout(() => {
                          try{
                          let x = onRejected(this.reason)   
                          resolvePromise(promise2,x,resolve,reject) 
                          }catch(e){
                              reject(e)
                          }
                      });
                  }
                  if(this.status === PENDING){
                      this.onResolveCallback.push(()=>{
                          setTimeout(() => {
                              try{
                                  let x = onFulfulled(this.value)
                                  resolvePromise(promise2,x,resolve,reject)
                              }catch(e){
                                  reject(e)
                              }
                          }); 
                      })
                      this.onRejectedCallback.push(()=>{
                          setTimeout(()=>{
                              try{
                                  let x = onRejected(this.reason)
                                  resolvePromise(promise2,x,resolve,reject)
                              }catch(e){
                                  reject(e)
                              }
                          })
                      })
                  }
              })
          return promise2
          }
      }
    
  • promise单元测试

    • 安装测试工具 npm install promises-aplus-tests -g
    • 开始测试: promises-aplus-tests mypromise.js
      Promise.deferred = function(){
          let dfd = {}
          dfd.promise = new Promise((resolve,reject)=>{
              dfd.resolve = resolve
              dfd.reject = reject
          })
          return dfd
      }
    
  • Promise相关方法

  • 实例方法

  • catch

     catch(onRejected){
          return this.then(null,onRejected)
      }
    
    • 静态方法
    • Resolve
      Promise.Resolve = (value)=>{
          return new Promise((resolve,reject)=>{
              resolve(value)
          })
      }
    
    • Reject
          Promise.Reject = (reason)=>{
          return new Promise((resolve,reject)=>{
              reject(reason)
          })
      }
    
    • all
      Promise.all=function(value){
          return new Promise((resolve, reject) => {
          let result = []
          let times = []
          function processMap (index, data) {
              result[index] = data
              if (times++ == value.length) {
                  resolve(result)
              }
          }
          for (let i = 0; i < value.length; ++i) {
              Promise.resolve(value[i]).then(data => {
                  processMap(i, data)
              }, reject)
          }
          }) 
      }
    
    • allSettled
      Promise.allSettled = function (value) {
    
          return new Promise((resolve, reject) => {
              let result = []
              let times = []
              function processMap (index, data) {
                  result[index] = data
                  if (times++ == value.length) {
                      resolve(result)
                  }
              }
              for (let i = 0; i < value.length; ++i) {
                  Promise.resolve(value[i]).then(data => {
                      processMap(i, { status: 'fulfilled', data })
                  }).catch(reason => {
                      processMap(i, { status: 'rejected', reason })
                  })
              }
          })
      }
    
    • race
      Promise.race = function(value){
          return new Promise((resolve,reject)=>{
              value.forEach(item=>{
                  Promise.resolve(item).then(resolve,reject)
              })
          })
      }
    

    *原型链方法

      Promise.prototype.finally = function(finall){
          return this.then((value)=>{
              return Promise.Resolve(finall()).then(()=>value)
          }, (finall)=>{
              return Promise.Reject(finall()).then(()=>{throw reason})
          })
      }
    
  • 将node函数转换成promise

      function promisify(fn){
          return function(...args){
              return new Promise((resolve,reject)=>{
                  fn(...args,function(err,data){
                      if(err){
                          reject(err)
                      }
                      resolve(data)
                  })
              })
          }
      }
    
      function promisifyAll(obj){
          for(let key in obj){
              if(typeof obj[key] == 'function'){
                  obj[key] = promisify(obj[key])
              }
          }
      } 
    
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-16 11:16:35  更:2022-05-16 11:18:19 
 
开发: 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/23 20:34:54-

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