用ES6-Class 手写一个Promise

Promise

异步神器Promise众所周知,解决了异步回调地狱问题,当然,在面试中也会问到一些实现原理或者让你 please write a Promise

  1. 先来一个简单版的Promise

回调特征:
1.PENDING=>默认状态
2.resolved => 成功
3.rejected => 失败

	 class MyPromise {
		  constructor(fn){
		    this.res = null;//存放成功的Value值
		    this.err = null;//存放失败的Value值
		    this.status = 'PENDING';//默认是PENGDING状态
		
		    try {
		      fn((res) => {
		      	 //调用该方法就是成功
		        this.status = 'resolved';
		        this.res = res;
		      }, (err) => {
		        //调用该方法就是失败
		        this.status = 'rejected';
		        this.err = err
		      })
		    } catch (error) {
		      console.log(error)
		    }
		  }
		  //成功的回调函数
		  then(onFulfilled, onRejected) {
		    let self = this;
		    if (this.status === 'resolved') {//成功
		      onFulfilled(self.res);
		    }
		    if (this.status === 'rejected') {//失败
		      onRejected(self.err);
		    }
		  }
}

我们试着使用一下

let p = new MyPromise((resolve,reject)=>{
    resolve('1')
})
p.then((res)=>{
  //成功的回调
  console.log(res,'成功')
},(err)=>{
  console.log(err,'失败')
})

//1 成功

现在已经实现了一个基础班的Promise,这里我们只处理了同步操作,但是如果是异步呢?我们试一下!

	let p = new MyPromise((resolve,reject)=>{
	  setTimeout(() => {
	    resolve('1')
	  }, 3000);
	})

	p.then((res)=>{
	  //成功的回调
	  console.log(res,'成功')
	},(err)=>{
	  console.log(err,'失败')
	})

发现并没有返回任何东西

因为 promise 调用 then 方法时,当前的 promise 并没有成功,一直处于 pending 状态。所以如果当调用 then 方法时,当前状态是 pending,我们需要先将成功和失败的回调分别存放起来,在异步任务被执行时,触发 resolve 或 reject,依次调用成功或失败的回调。

结合这个思路,我们优化一下代码:


//please write a Promise!!!
 class MyPromise {
  constructor(fn){
    this.res = null;
    this.err = null;
    this.status = 'PENDING';

    this.onResolveCallbacks = [];//存放成功的回调
    this.onRejectCallbacks = [];//存放失败的回调


    try {
      fn((res) => {
        this.status = 'resolved';
        this.res = res;
        this.onResolveCallbacks.forEach(fn => fn())
      }, (err) => {
        this.status = 'rejected';
        this.err = err
        this.onRejectCallbacks.forEach(fn => fn())
      })
    } catch (error) {
      console.log(error)
    }

  }
  //成功的回调函数
  then(onFulfilled, onRejected) {
    let self = this;
    if (this.status === 'resolved') {//成功
      onFulfilled(self.res);
    }

    if (this.status === 'rejected') {//失败
      onRejected(self.err);
    }

	//如果promise的状态是 pending,需要将 onFulfilled 和 onRejected 函数存放起来,等待状态确定后,再依次将对应的函数执行
    if (this.status === 'PENDING'){
      this.onResolveCallbacks.push(()=>{
        onFulfilled(self.res)
      })
      this.onRejectCallbacks.push(() => {
        onFulfilled(self.err)
      })
    }
  }
}

let p = new MyPromise((resolve,reject)=>{
  setTimeout(() => {
    resolve('1')
  }, 3000);
})

p.then((res)=>{
  //成功的回调
  console.log(res,'成功')
},(err)=>{
  console.log(err,'失败')
})

你可能感兴趣的:(前端)