首页 > 其他分享 >promise实现

promise实现

时间:2024-04-15 10:00:11浏览次数:16  
标签:function resolve return 实现 self MyPromise promise reject

// 定义状态常量
const PENDING = 'pending',
  FULFILLED = 'fulfilled',
  REJECTE = 'reject'
function MyPromise(executor) {
  const self = this // 缓存promise对象
  // 初始执行 状态为pending
  self.status = PENDING
  // 成功回调
  self.onResolveCb = []
  // 失败回调
  self.onRejectedCb = []
  // 成功执行函数
  function resolve(value) {
    // 如果promise 返回值为一个promise 则执行zhen 方法并传入resolve与reject函数
    if (value instanceof MyPromise) {
      return value.then(resolve, reject)
    }
    // 只有等待态调用该函数,状态才会转为成功态
    if (self.status === PENDING) {
      self.status = FULFILLED
      // 成功后获得值,不可修改
      self.value = value
      // 调用所有成功回调
      self.onResolveCb.forEach((cb) => cb(value))
    }
  }
  function reject(reason) {
    // 只有等待态调用该函数,状态转为失败态
    if (self.status === PENDING) {
      self.status = REJECTE
      // 失败后获得值,不可修改
      self.value = reason
      // 调用所有失败回调
      self.onRejectedCb.forEach((cb) => cb(reason))
    }
  }
  try {
    // 函数执行可能报错,报错则需要reject
    executor(resolve, reject)
  } catch (e) {
    reject(e)
  }
}

MyPromise.prototype.then = function (onFulFilled, onRejected) {
  // 如果没有传成功回调函数,则赋值一个默认函数
  onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : (value) => value
  onRejected =
    typeof onRejected === 'function'
      ? onRejected
      : (reason) => {
          throw new e(reason)
        }

  let self = this
  let promise2
  if (self.status === FULFILLED) {
    console.log('then fulfilled')
    return (promise2 = new MyPromise((resolve, reject) => {
      // 所有成功与失败设置为异步,下一个事件循环执行,保证用户excutor中的代码先执行完成然后再执行onFulfilled回调
      setTimeout(() => {
        try {
          let x = onFulFilled(self.value)
          // 解析then中返回的promise
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
    }))
  }
  if (self.status === REJECTE) {
    promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        try {
          let x = onRejected(self.value)
          resolvePromise(promise2, x, resolve, reject)
        } catch (e) {
          reject(e)
        }
      })
    })
    return promise2
  }
  if (self.status === PENDING) {
    console.log('then pending')
    // pending状态添加成功回调
    self.onResolveCb.push(() => {
      return (promise2 = new MyPromise((resolve, reject) => {
        setTimeout(() => {
          try {
            let x = onFulFilled(self.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      }))
    })
    // pending状态添加失败回调
    self.onRejectedCb.push(() => {
      return (promise2 = new MyPromise((resolve, reject) => {
        setTimeout(() => {
          try {
            let x = onRejected(self.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      }))
    })
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  // let p2 = p1.then(() => p2)
  console.log('resolve Promise')
  let called = false
  if (promise2 === x) {
    return reject(new Typee('循环引用'))
  }
  if (x instanceof MyPromise) {
    if (x.status === PENDING) {
      x.then(function (y) {
        resolvePromise(promise2, y, resolve, reject)
      }, reject)
    } else {
      x.then(resolve, reject)
    }
    // thenable Object 有then方法的对象或者方法
  } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
    // 当then为get属性的时候,可以设置抛出异常
    try {
      console.log('应该执行到这里', typeof x.then === 'function')

      let then = x.then
      if (typeof then === 'function') {
        then.call(
          function () {
            console.log('执行到here')

            if (called) return
            called = true
            resolvePromise(promise2, x, resolve, reject)
          },
          function (e) {
            if (called) return
            called = true
            reject(e)
          }
        )
      } else {
        // 到此表示x.then 不存在 或者不是一个函数
        resolve(x)
      }
    } catch (e) {}
    // 字符串或其他基本数据
  } else {
    if (called) return
    called = true
    resolve(x)
  }
}
MyPromise.prototype.catch = function (onRejected) {
  this.then(null, onRejected)
}

MyPromise.deferred = MyPromise.defer = function () {
  let defer = {}
  defer.promise = new MyPromise(function (resolve, reject) {
    defer.resolve = resolve
    defer.reject = reject
  })
  return defer
}
MyPromise.all = function (promises) {
  return new MyPromise((resolve, reject) => {
    const result = []
    // count 不能定义在done里面 不然每次都会初始化为0,计数错误
    let count = 0
    function done(index) {
      return function (data) {
        result[index] = data
        if (++count === promises.length) {
          resolve(result)
        }
      }
    }
    promises.forEach((promise, index) => {
      promise.then(done(index), reject)
    })
  })
}
MyPromise.race = function (promises) {
  return new MyPromise((resolve, reject) => {
    promises.forEach((promises) => {
      promises.then(resolve, reject)
    })
  })
}
MyPromise.resolve = function (value) {
  return new MyPromise((resolve) => resolve(value))
}
MyPromise.reject = function (reason) {
  return new MyPromise(resolve, (reject) => reject(reason))
}
/**
 * 2
 */
// const ps = [
//   new MyPromise((resolve, reject) => {
//     resolve(122)
//     setTimeout(() => {
//       reject(1)
//     }, 1000)
//   }),
//   new MyPromise((resolve, reject) => {
//     setTimeout(() => {
//       resolve(2)
//     }, 1000)
//   })
// ]
// const p1 = MyPromise.race(ps).then(
//   (data) => {
//     console.log('data', data)
//   },
//   (err) => {
//     console.log('err', err)
//   }
// )
/**
 * 1.
 */
// const p1 = new MyPromise((resolve, reject) => {
//   const num = Math.random()
//   if (num > 0.5) {
//     console.log('222')
//     resolve(23323)
//     setTimeout(() => {
//       resolve(num)
//     }, 1000)
//   } else {
//     reject(num)
//   }
// })
// // const p2 = p1.then();
// let p2 = p1.then(
//   (data) => {
//     console.log('data', data)

//     // return p2
//   },
//   (err) => {
//     console.log('err', err)
//     // return p2
//   }
// )
// p2.then(
//   (data) => {
//     console.log('p2 data', data)
//   },
//   (err) => {
//     console.log('p2 err', err)
//   }
// )

const pr1 = new MyPromise((resolve) => {
  resolve(100)
})
const pr2 = pr1.then((data) => {
  console.log('datapro1', data)

  return new Promise((resolve) => {
    resolve(data)
  })
})
pr2.then((data) => console.log('datapro2', data))

标签:function,resolve,return,实现,self,MyPromise,promise,reject
From: https://www.cnblogs.com/coderzdz/p/18135230

相关文章

  • 深入理解DES算法:原理、实现与应用
    title:深入理解DES算法:原理、实现与应用date:2024/4/1421:30:21updated:2024/4/1421:30:21tags:DES加密对称加密分组密码密钥管理S盒P盒安全性分析替代算法DES算法简介历史DES(DataEncryptionStandard)算法是由IBM研发,并于1977年被美国国家标准局(NBS,现NIST......
  • Go实践:用Sync.Map实现简易内存缓存系统
    介绍定义了一个Cache结构体,其中使用sync.Map作为底层数据结构来存储缓存项。Set方法用于设置缓存项,指定键、值以及过期时间。Get方法用于获取缓存项,如果缓存项存在且未过期,则返回值和true,否则返回nil和false。方法的接受者为指针类型,是为了对Cache对象进行操作,并在方法内部访问和......
  • Conditional AutoEncoder的Pytorch完全实现
    一个完整的深度学习流程,必须包含的部分有:参数配置、Dataset和DataLoader构建、模型与optimizer与Loss函数创建、训练、验证、保存模型,以及读取模型、测试集验证等,对于生成模型来说,还应该有重构测试、生成测试。AutoEncoder进能够重构见过的数据、VAE可以通过采样生成新数据,对于MN......
  • Go语言实现指纹识别
    指纹识别指纹识别是一种用于识别网络设备、操作系统、应用程序或用户的技术。它通过收集和分析目标系统的特征信息,如网络协议、端口号、操作系统版本、应用程序版本等,来确定系统的身份或特征。指纹识别可以用于多种用途,包括网络侦察、入侵检测、安全审计等。常用的指纹识别方法:......
  • 原型设计工具比较及实现
    墨刀(Moqups):适用领域:墨刀适用于快速创建简单的原型和线框图,特别是对于初学者和小型团队来说非常友好。它在用户界面设计方面有一些基本的功能,可以用于创建简单的交互式原型。墨刀提供了在线协作和共享功能,使团队成员可以轻松共享和编辑原型。优点:简单易用,适合新手上手和快速......
  • redis为什么一定要用跳表实现有序集合,却不用平衡树,红黑树或者B+树呢?
    平衡树vs跳表平衡树必须满足所有节点的左右子树高度差不超过1,也就是平衡因子范围为[-1,1]。但是对于范围查询来说,利用平衡树通过中序遍历达到和跳表一样的效果,但是平衡树的每一次插入或者删除操作都需要保证整棵树的绝对平衡,只要不平衡就会通过旋转的方式来重新保持平衡,这个过......
  • 【数学】向量点乘、叉乘的理论、应用及代码实现(C++)
    前言我总结了一下向量点乘,叉乘的概念,以及他们的应用及相关C++代码的实现。blog这类问题也是技术面试经常碰到的,一次研究透了会有收获。1向量向量具有大小和方向。共线向量:两个平行的向量为共线向量。1.1叉积CrossProduct$$\vec{a}\times\vec{b}=|\vec{a}||\vec{b}|\sin......
  • 企业如何根据业务需求实时调整网络资源,实现资源的动态分配和优化?
    云联网以其“一点上云,多云互联”的特性,为中国联通提供了极大的便利。通过云联网,企业可以轻松地将其业务部署到云端,实现资源的快速调配和共享。同时,云联网支持多云环境的互联互通,使得企业能够灵活地选择不同云服务商,构建多元化的云生态,从而满足其多样化的业务需求。广泛覆盖和互联......
  • 实现自定义注解校验方法参数(AOP+自定义注解+自定义异常+全局异常捕获)
    一、实现目的在编写接口的时候,通常会先对参数进行一次校验,这样业务逻辑代码就略显冗杂,如果可以把校验参数的代码进行统一管理,在方法或者属性上直接添加注解就可以实现参数的校验,就可以提升代码编写的效率。二、实现原理通过自定义注解,注解在入参VO的属性上,设定需要满足的条件,然......
  • 【Linux系统编程】libevent库实现简易tcp服务器
    libevent库实现简易tcp服务器流程分析创建socket,设置端口复用,绑定四元组,开始监听。初始化event_base结构体。编写监听事件的回调函数和客户端读事件的回调函数。初始化tcp监听事件,并加入event_base中。开始event事件处理循环。释放所有事件占用资源。释放event_base占用......