面试题:手写Promise

Promise构造函数返回一个Promise对象实例,在使用new关键字调用Promise构造函数时,在合适的时机调用executor的参数resolve,并将resolve处理后的值作为resolve的函数参数执行,这个值可以在后续的then方法的第一个函数参数中获取。同理,在出现错误时,调用executor的参数reject,并将错误信息作为reject的函数参数执行,这个错误信息可以在后续then方法的第二个函数参数中获取。

function Promise(executor){
  // 存储Promise的状态
  this.status = 'pending';
  // 存储resolve处理后的值
  this.value = null;
  // 存储reject处理后的值
  this.reason = null;
  // 存储调用then方法传递的onFulfilled函数
  this.onFulfilledArray = [];
  // 存储调用then方法传递的onRejected函数
  this.onRejectedArray = [];
  function resolve(value){
    if(value instanceof Promise){
      return value.then(resolve, reject);
    }
    setTimeout(() => {
    	 if(this.status === 'pending'){
           this.status = 'fulfilled';
           this.onFulfilledArray.forEach(onFulfilled => {
             onFulfilled(value);
           });
         }
    });
  }

  function reject(reason){
  	setTimeout(() => {
		if(this.status === 'pending'){
      		this.status = 'rejected';
      		this.onRejectedArray.forEach(onRejected => {
       		 onRejected(reason);
      		});
    	}
	}); 
  }
  try{
    executor(resolve,reject);
  }catch(e){
    reject(e);
  }
}

构造函数返回的Promise对象具有一个then方法。在then方法中调用者可以定义两个参数,分别是onFulfilled和onRejected它们都是函数类型的参数。onFulfilled通过参数可以获取Promise对象经过resolve处理后的值,onRejected可以获取Promise对象经过reject处理后的值。

Promise.prototype.then = function (onFulfilled,onRejected){
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : data => data;
  onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason};
  let promise2;
  if(this.status === 'fulfilled'){
    return promise2 = new Promise((resolve,reject) => {
    	setTimeout(() => {
    		try{
        		let result = onFulfilled(this.value);
        		resolvePromise(result,promise2, resolve,reject);
      		}catch(e){
        		reject(e);
      		}
    	});
    });
  }
  if(this.status === 'rejected'){
    return promise2 = new Promise((resolve, reject) => {
    	setTimeout(() => {
			try {
        		let result = onRejected(this.reason);
        		resolvePromise(result, promise2, resolve, reject);
      		} catch (e) {
        		reject(e);
      		}
		});
    });
  }
  if(this.status === 'pending'){
    return promise2 = new Promise((resolve, reject) => {
      this.onFulfilledArray.push(() => {
        try {
          let result = onFulfilled(this.value);
          resolvePromise(result, promise2, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
      this.onRejectedArray.push(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(result, promise2, resolve, reject);
        } catch (e) {
          reject(e);
        }
      });
    });
  }
}
// 把onFulfilled和onRejected处理的结果转换成Promise实例,因为then方法需要返回一个Promise实例,该实例的值是onFulfilled参数的返回值。把这个操作抽象为resolvePromsie函数以便复用。
function resolvePromise(result,promise2, resolve, reject){
// 当result和promise2相等时也就是onFulfilled返回promise2时,抛错
  if(result == promise2){
    reject(new Error('error due to circle reference'));
  }
  // 是否已经执行onFulfilled或onRejected
  let consumed = false;
  let thenable;
  if(result instanceof Promise){
    if(result.status === 'pending'){
      result.then((data) => {
        resolvePromise(data,promise2, resolve, reject);
      },reject);
    } else {
      result.then(resolve,reject);
    }
    return;
  }
  let isComplexResult = (target) => {
    return typeof (target === 'function' || typeof target === 'object') && (target !== null);
  }
  // 如果返回的是疑似Promise类型
  if(isComplexResult(result)){
    try{
      thenable = result.then;
      // 判断返回值是否是Promise类型
      if(typeof thenable === 'function'){
        thenable.call(result, function (data){
          if(consumed){
            return;
          }
          consumed = true;
          return resolvePromise(data, promise2, resolve, reject)
        }, function (error){
          if(consumed){
            return;
          }
          consumed = true;
          return reject(error);
        });
      } else {
        resolve(result);
      }
    }catch(e){
      if(consumed){
        return;
      }
      consumed = true;
      return reject(e);
    }
  }else {
    resolve(result);
  }
}

捕获状态为rejected的promise并执行回调。

Promise.prototype.catch() = function (catchFunc){
  return this.then(null, catchFunc);
}

返回一个状态为fulfilled的新的promise

Promise.resolve = function (value){
  return new Promise((resolve,reject) => {
    resolve(value);
  });
}
Promise.reject = function (reason){
  return new Promise((resolve, reject) => {
    reject(reason);
  });
}

Promise.all方法返回一个Promise实例,该实例的状态在参数内的所有Promise都为fulfilled时为fulfilled。如果参数中的任意一个Promise的实例的状态为rejected实例的状态为rejected。

Promise.all = function (promsieArr){
  if(!Array.isArray(promsieArr)){
    throw new Error('the arguments shoule be an array');
  }
  return new Promise((resolve,reject) => {
    try{
      let resultArray = [];
      for(let i = 0, len = promsieArr.length; i<len;i++){
        let promiseItem = promsieArr[i];
        promiseItem.then(data => {
          resultArray.push(data);
          if(resultArray.length == len){
            resolve(resultArray);
          }
        },reject);
      }
    }catch(e){
      reject(e);
    }
  });
}

race()方法返回一个新的promise,该promise的状态是传递的数组中的第一个决议的promise,不管是fulfilled还是rejected。

Promise.race = function (promsieArr){
  if (!Array.isArray(promsieArr)) {
    throw new Error('the arguments shoule be an array');
  }
  return new Promise((resolve,reject) => {
    try{
      for(let i = 0, len = promsieArr.length; i < len; i++){
        let promiseItem = promsieArr[i];
        promiseItem.then(resolve,reject);
      }
    }catch(e){
      reject(e);
    }
  });
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端御书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值