手写Promise实现

本文详细介绍了如何使用构造函数方式实现Promise,并展示了如何编写then、reject、resolve、all和race等方法,以及通过链式调用来测试Promise的行为。
摘要由CSDN通过智能技术生成

一、前言

  阅读参考资料,本文整理出使用 构造函数 手撕出 Promise 的方法,在整理过程中不断添加注解以示思路。有错请指出哟,一起进步!!!class 实现 Promise 请查看参考资料,该作者写得非常好、非常详细!!!
  参考资料:promise原理手写实现promise以及async await

二、代码

// 构造函数
function MyPromise(executor) {
  // 添加属性
  this.PromiseState = 'pending'
  this.PromiseResult = null
  // 保存实例对象的this
  const self = this
  // 声明属性
  // this.callbacks = {}
  this.callbacks = []
  
  function resolve(data){
    // 判断状态
	// 普通函数的this一般指window对象
	// 错误写法:直接this.PromiseState !== 'pending'
    if(self.PromiseState !== 'pending')return
    // 修改对象状态
    self.PromiseState = 'fulfilled'
    // 设置对象结果
    self.PromiseResult = data
    // 调用回调函数
    // if(self.callbacks.onFulfilled) {
    //   onFulfilled(data)
    // }
	setTimeout(() => {
	  self.callbacks.forEach(item => {
        item.onFulfilled(data)
      })
	})
  }
  function reject(reason) {
    if(self.PromiseState !== 'pending')return
    self.PromiseState = 'rejected'
    self.PromiseResult = reason
	// js执行顺序:同步任务 > Promise.then() > setTimeout() 
	setTimeout(() => {
	  self.callbacks.forEach(item => {
        item.onRejected(reason)
      })
	}) 
  }
  try {
	// executor是一个函数,resolve函数和reject函数作为参数传递
	// 生成Promise实例时就执行
    executor(resolve, reject)
  } catch(e) {
    reject(e)
  }
}

// 添加then方法
// then方法返回的是一个Promise对象,方便链式调用
MyPromise.prototype.then = function(onFulfilled, onRejected) {
  // 要将实例的this保存下来,普通函数的this指向window对象
  const self = this
  // 判断回调函数参数
  if(typeof onRejected !== 'function') {
    onRejected = reason => {
      throw reason
    }
  }
  if(typeof onFulfilled !== 'function') {
    onFulfilled = data => data
  }
  return new MyPromise((resolve, reject) => {
    // 封装回调函数
    function callback(type) {
      try {
		// 获取回调函数的结果
        let result = type(self.PromiseResult)
        if(result instanceof MyPromise) {
          result.then(data => {
            resolve(data)
          }, reason => {
            reject(reason)
          })
        } else {
          resolve(result)
        }
      } catch(e) {
        reject(e)
      } 
    }
    if(this.PromiseState === 'fulfilled') {
      callback(onFulfilled)
    }
    if(this.PromiseState === 'rejected') {
      callback(onRejected)
    }
	if(this.PromiseState === 'pending') {
      this.callbacks.push({
        onFulfilled: function() {
          callback(onFulfilled)
        },
        onRejected: function() {
          callback(onRejected)
        }
      })
    }
  })
}

// 添加catch方法
// 1、当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调
// 2、前面任何操作出了异常, 都会传到最后失败的回调中处理
MyPromise.prototype.catch = function(onRejected) {
  return this.then(undefined, onRejected)
}

// 添加resolve静态方法
// 静态方法直接绑定到构造函数上,而不是绑定到实例对象上。
// 只能通过构造函数本身调用,实例对象不能调用
MyPromise.resolve = function(data) {
  // 返回Promise对象
  return new MyPromise((resolve, reject) => {
    if(data instanceof MyPromise) {
      data.then(data => {
        resolve(data)
      }, reason => {
        reject(reason)
      })
    } else {
      resolve(data)
    }
  })
}

// 添加reject方法
MyPromise.reject = function(reason) {
  return new MyPromise((resolve, reject) => {
    reject(reason)
  })
}

// 添加all方法
MyPromise.all = function(promises) {
  // promises是n个Promise对象
  // 结果返回一个新的 promise,只有所有的 promise 都成功才成功,只要有一个失败了就直接失败
  return new MyPromise((resolve, reject) => {
	let count = 0
	let arr = []
	for(let i = 0; i < promises.length; i++) {
	  promises[i].then(data => {
		count++
		arr[i] = data
		// 关键:判断是否所有promises都成功
		if(count === promises.length) {
		  resolve(arr)
		}
	  }, reason => {
		reject(reason)
	  })
	}
  })	
}

// 添加race方法
MyPromise.race = function(promises) {
  // 返回一个新的 promise
  // 第一个完成的 promise 的结果状态就是最终的结果状态,谁先完成就输出谁(不管是成功还是失败)
  return new MyPromise((resolve, reject) => {
	for(let i = 0; i < promises.length; i++) {
	  promises[i].then(data => {
		resolve(data)
	  }, reason => {
		reject(reason) 
	  })
	}
  })
}

三、测试

// Promise链式调用:链式调用意味着你可以在一个Promise完成后,用then方法链式调用另一个Promise。
const p = new MyPromise((resolve, reject) => {
  resolve('resolved')
}).then(data => {
  return new MyPromise((resolve, reject) => {
	resolve('resolved again')
  })
}).then(data=>{
  console.log(data)
})
console.log('-----------------------------')

const p1 = new MyPromise((resolve, reject) => {
  resolve('ok')
})
const p2 = MyPromise.resolve('oh yeah')
const p3 = MyPromise.reject('error')
const p4 = MyPromise.resolve('oh yeah yeah')

const result1 = MyPromise.all([p1, p2, p3])
console.log('all_rejected\n', result1)
console.log('-----------------------------')
const result2 = MyPromise.all([p1, p2, p4])
console.log('all_fulfilled\n',result2)
const result3 = MyPromise.race([p1, p2, p3])
console.log('-----------------------------')
console.log('race\n',result3)

四、测试结果

在这里插入图片描述

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值