难点与解决方案:

  1. promise中包裹了异步任务的处理
    1. 实例调用then方法时,将then中的回调函数保存起来
    2. 当promise中的resolve或者reject执行时,执行then办法保存起来的回调函数
    3. 由于一个实例可以调用多次then方法,而每一个then的回调都要执行,因此存于一个数组中
  2. then方法的回调返回值也是promise
    1. then返回的promise实例的状态和值,等同于then的回调返回的promis实例的状态和值
  3. 异常穿透
    1. then方法中,如果第二个参数没有值(或者不是函数),则重写该回调,使其为一个函数,并抛出上一个promise失败的结果,实现异常穿透

      方式一:使用构造函数封装

      ```javascript // 定义构造函数 function Promise(executor) { this.PromiseState = ‘pending’ // 记录状态 this.PromiseResult = undefined // 记录返回值 this.callbacks = [] // 存放then的回调函数,处理异步事件,使用数组可存多个then的回调函数 // 定义resolve函数 function resolve(data) { if (this.PromiseState !== ‘pending’) return // 如果状态已经改变,则不执行下面的代码 this.PromiseState = ‘fulfilled’ // 改变状态 this.PromiseResult = data // 存入结果值 // 异步执行,调用then中的回调函数 this.callbacks.forEach(item => { if (item.onResolve) item.onResolve(data) // 执行then中的成功回调 }); } // 定义reject函数 function reject(data) { if (this.PromiseState !== ‘pending’) return this.PromiseState = ‘rejected’ this.PromiseResult = data // 异步执行,调用then中的回调函数 this.callbacks.forEach(item => { if (item.onReject) item.onReject(data) }); } try { // 执行new promise传入的回调 executor(resolve.bind(this), reject.bind(this)) } catch (err) { reject.call(this, err) // 记录失败原因,并改变状态 } }

// 定义then方法 Promise.prototype.then = function (onResolve, onReject) { // 保存this let self = this // 判断then传入的回调是不是函数,实现异常穿透 if (typeof onReject !== “function”) onReject = err => { throw err } if (typeof onResolve !== “function”) onResolve = res => res // then方法返回一个promise return new Promise((resolve, reject) => { // 使用箭头函数this指向调用then的Promise // 声明一个函数,用来改变then返回的promise的状态,type为then的第几个参数 let callback = function (type) { try { let res = type(self.PromiseResult) // 如果then的回调函数返回了一个promise // 那then返回的promise的状态和值就等于这个promise的状态和值 if (res instanceof Promise) {
res.then(r => { resolve(r) // 改变状态为成功,并记录返回的结果 }, e => { reject(e) // 改变状态为失败,并记录返回的结果 }) } else { // 回调返回的不是promise resolve(res) } } catch (err) { // 回调函数抛错 reject(err) // 改变状态为失败 } } // 如果promise的状态已经成功 if (this.PromiseState === ‘fulfilled’) { callback(onResolve) // 如果promise状态是失败 } else if (this.PromiseState === ‘rejected’) { callback(onReject) } else { // 如果promise的状态是pending,也就是promise中有异步任务 // 有多个回调都要保存,所以存在一个数组中 this.callbacks.push({ onResolve: function () { callback(onResolve) }, onReject: function () { callback(onReject) } }) } }) }

// 定义catch方法,调用then的异常处理方法即可 Promise.prototype.catch = function (onReject) { return this.then(undefined, onReject) }

  1. <a name="loVx3"></a>
  2. ## 方式二:class定义类
  3. > 思路与构造函数封装promise一致
  4. ```javascript
  5. class Promise {
  6. constructor(executor) {
  7. this.PromiseState = 'pending' // 记录状态
  8. this.PromiseResult = undefined // 记录返回值
  9. this.callbacks = [] // 记录then的回调
  10. // 执行promise的传入的回调函数
  11. try {
  12. executor(this.resolve.bind(this), this.reject.bind(this))
  13. } catch (error) {
  14. this.reject.call(this, error)
  15. }
  16. }
  17. resolve(data) {
  18. if (this.PromiseState !== "pending") return
  19. this.PromiseState = 'fulfilled'
  20. this.PromiseResult = data
  21. // 异步执行,调用then中的回调函数
  22. this.callbacks.forEach(item => {
  23. item.onResolve(data)
  24. })
  25. }
  26. reject(data) {
  27. if (this.PromiseState !== "pending") return
  28. this.PromiseState = 'rejected'
  29. this.PromiseResult = data
  30. this.callbacks.forEach(item => {
  31. item.onReject(data)
  32. })
  33. }
  34. // 定义promise的then方法
  35. then(onResolve, onReject) {
  36. let self = this
  37. // 处理异常穿透
  38. if(typeof onResolve !== 'function') onResolve=res=>res
  39. if(typeof onReject !== 'function') onReject=err=>{throw err}
  40. // then方法返回一个promis实例
  41. return new Promise((resolve, reject) => {
  42. // 处理then的参数的返回值
  43. function resultThen(type) {
  44. try {
  45. let res = type(self.PromiseResult) // 执行then的回调函数,并获取返回值
  46. if (res instanceof Promise) { // then的回调的返回值如果是promise
  47. res.then(r => {
  48. resolve(r)
  49. }, e => {
  50. reject(e)
  51. })
  52. } else {
  53. resolve(res)
  54. }
  55. } catch (error) {
  56. reject(error)
  57. }
  58. }
  59. // 判断promise实例的状态,并做对应处理
  60. if (this.PromiseState === 'fulfilled') {
  61. resultThen(onResolve)
  62. } else if (this.PromiseState === 'rejected') {
  63. resultThen(onReject)
  64. } else { // promise是pending状态
  65. this.callbacks.push({ // 将then的回调保存起来
  66. onResolve: function () {
  67. resultThen(onResolve)
  68. },
  69. onReject: function () {
  70. resultThen(onReject)
  71. }
  72. })
  73. }
  74. })
  75. }
  76. // 定义promise的catch方法,等同于调用的then方法传入第二个参数
  77. catch(onReject){
  78. return this.then(undefined,onReject)
  79. }
  80. }