面试官让我手写promise,我这样写,他很满意

导语:
你肯定使用过promise,但是你知道它是怎么实现的吗?它的原理是怎么样的?你能手写一个简单的promise吗?
在面试中你也可能会被问到手写一个promise,现在来直接手撕原理和代码吧!!

一,promise的状态

promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

一开始的时候就是pending,随后经过操作就会产生出另外两种状态fulfilled和rejected,并且可以通过这两个状态去调用不同的处理函数。

二,仅仅考虑resolve和reject

首先我们先写一个class的构造函数,并且把默认state设置为pending,它的value和reason设置为null。

class Promise{
  constructor(executor){
    this.state = 'pending';			//默认的状态,进行中
    this.value = null;				//成功后携带的值
    this.reason = null;				//失败后携带的原因
	this.onFulfilledCallbacks = []
  	this.onRejectedCallbacks = []
  	
    function resolve(value) {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(item => item(this.value))
      }
    };

    function reject(reason) {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(item => item(this.reason))
      }
    };

    try{
      executor(resolve, reject);		//构造
    } catch (err) {
      reject(err);
    }
  }
  //then函数根据state来进行后续的回调函数操作
  then(onFulfilled,onRejected) {		
    if (this.state === 'fulfilled') {
      onFulfilled(this.value);
    };
    if (this.state === 'rejected') {
      onRejected(this.reason);
    };
    if (this.state === 'pending') {
	  this.onFulfilledCallbacks.push(onFulfilled)
	  this.onRejectedCallbacks.push(onRejected)
    }
  }
}

三,考虑能够链式then

如果要能够进行链式的then,那么肯定是要返回一个promise,才能够这样串联起来。所以我们要对刚刚的代码进行小小的修改,让then执行回调函数的时候,返回一个promise。

class Promise{
  constructor(executor){
    this.state = 'pending';			//默认的状态,进行中
    this.value = null;				//成功后携带的值
    this.reason = null;				//失败后携带的原因
	this.onFulfilledCallbacks = []
  	this.onRejectedCallbacks = []
  	
    function resolve(value) {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(item => item(this.value))
      }
    };

    function reject(reason) {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(item => item(this.reason))
      }
    };

    try{
      executor(resolve, reject);		//构造
    } catch (err) {
      reject(err);
    }
  }
  //then函数根据state来进行后续的回调函数操作
  then(onFulfilled,onRejected) {		
    if (this.state === 'fulfilled') {
	    return new Promise((resolve, reject) => {
	      onFulfilled(this.value)
	    })
    };
    if (this.state === 'rejected') {
      	return new Promise((resolve, reject) => {
	      onRejected(this.reason)
	    })
    };
    if (this.state === 'pending') {
	  	return new Promise((resolve, reject) => {
	      this.onFulfilledCallbacks.push(onFulfilled)
	      this.onRejectedCallbacks.push(onRejected)
	    })
    }
  }
}

这样写后,我们就可以进行链式操作,比如promise.then().then()…,这样无限串联,解决了回调函数的回调地狱问题。

四,考虑链式,也考虑then也可能是返回一个值

class Promise{
  constructor(executor){
    this.state = 'pending';			//默认的状态,进行中
    this.value = null;				//成功后携带的值
    this.reason = null;				//失败后携带的原因
	this.onFulfilledCallbacks = []
  	this.onRejectedCallbacks = []
  	
    function resolve(value) {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(item => item(this.value))
      }
    };

    function reject(reason) {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(item => item(this.reason))
      }
    };

    try{
      executor(resolve, reject);		//构造
    } catch (err) {
      reject(err);
    }
  }
  //then函数根据state来进行后续的回调函数操作
  then(onFulfilled,onRejected) {		
    if (this.state === 'fulfilled') {
	    return new Promise((resolve, reject) => {
	      try {
	        let f = onFulfilled(self.value)
	        if (f instanceof Promise) {
	          f.then(resolve, reject)
	        } else {
	          resolve(f)
	        }
	      } catch (err) {
	        reject(err)
	      }
	    })
    };
    if (this.state === 'rejected') {
      	return new Promise((resolve, reject) => {
	      try {
	        let j = onRejected(self.reason)
	        if (j instanceof Promise) {
	          j.then(resolve, reject)
	        } else {
	          resolve(j)
	        }
	      } catch (err) {
	        reject(err)
	      }
	    })
    };
    if (this.state === 'pending') {
	  	return new Promise((resolve, reject) => {
	      self.onFulfilledCallbacks.push(() => {
	        let f = onFulfilled(self.value)
	        if (f instanceof Promise) {
	          f.then(resolve, reject)
	        } else {
	          resolve(f)
	        }
	      })
	      self.onRejectedCallbacks.push(() => {
	        let j = onRejected(self.reason)
	        if (j instanceof Promise) {
	          j.then(resolve, reject)
	        } else {
	          resolve(j)
	        }
	      })
	    })
    }
  }
}

这样的话promise也能返回一个值,并且被后续的then获取到。

猜你喜欢

转载自blog.csdn.net/gitchatxiaomi/article/details/108297627