彻底搞懂系列———promise

Promise主要功能
  1. class类和三种状态
  2. 两种返回resolve、reject
  3. then函数的链式结构
  4. catch错误处理
  5. 静态调用方法resolve和reject
  6. all方法
  7. rece方法
class类
// 静态方法判断是否是函数
const isFunction = (varibale) => typeof variable === "function";
// 三种状态
const PENDING = "PENDING";
const FUIFILLED = "FULFILLED";
const REJECT = "REJECT";
class Promise{
	constructor(handle) {
		if(!isFunction(handle)){
			throw new Error("Promise must accept a  function as a parameter")
		}
		// 状态控制(初始化为PENDING)
		this.status = PENDING;
		// 返回数据(初始化为undefined)
		this.value = undefined;
		// 两个添加成功和失败回调函数的队列
		this.fulfilledQueues = [];
		this.rejectedQueues = [];
		// 执行handle
		try {
			// 传进两种回调,提供使用
			handle(this.resolve.bind(this),this.reject.bind(this));
		} catch (err) {
			this.reject(err)
		}
	}
}

使用时:

new MyPromise((resolve, reject) => {
 
});

就是上面的 handle(this.resolve.bind(this),this.reject.bind(this));执行

resolve、reject两个函数(都要判断status必须是PENDING)
// 当执行resolve('成功了')
resolve(val){
	const run = () => {
		if(this.status !== PENDING) return;
		this.status = FULFILLED;
		// 用来执行成功队列
		const runFulfilled = (value) => {
			let cb;
			while ((cb = this.fulfilledQueues.shift())) {
				cb(value)
			}
		}
		// 用来执行失败队列
		const runRejected = (err) => {
			let cb;
			while ((cb = this.rejectedQueues.shift())) {
				cb(err)
			}
		}
		// 如果resolve参数是Promise则执行一次then
		if(val instanceof Promise){
			val.then(
				(value) => {
					this.value = value;
					runFulfilled(value)
				},
				(err) => {
					this.value = err;
					runRejected(err)
				},
			)
		}else{
			this.value = val;
			runFulfilled(val)
		}
	}
	// 异步执行
	setTimeout(run,0)
}
// 当执行reject('失败了')
reject(err) {
    if (this._status !== PENDING) return;
    // 依次执行失败队列中的函数,并清空队列
    const run = () => {
	     this._status = REJECTED;
	      this._value = err;
	      let cb;
	      while ((cb = this._rejectedQueues.shift())) {
	        	cb(err);
	      }
    };
    // 异步执行
    setTimeout(run, 0);
}
then函数的链式结构

因为是链式结构所以then函数返回的也必须是Promise

 then(onFulfilled, onRejected) {
    const { _value, _status } = this;
    // 返回一个新的Promise对象
    return new MyPromise((onFulfilledNext, onRejectedNext) => {
      // 封装一个成功时执行的函数
      let fulfilled = (value) => {
        try {
          if (!isFunction(onFulfilled)) {
            onFulfilledNext(value);
          } else {
            let res = onFulfilled(value);
            if (res instanceof MyPromise) {
              // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
              res.then(onFulfilledNext, onRejectedNext);
            } else {
              //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
              onFulfilledNext(res);
            }
          }
        } catch (err) {
          // 如果函数执行出错,新的Promise对象的状态为失败
          onRejectedNext(err);
        }
      };
      // 封装一个失败时执行的函数
      let rejected = (error) => {
        try {
          if (!isFunction(onRejected)) {
            onRejectedNext(error);
          } else {
            let res = onRejected(error);
            if (res instanceof MyPromise) {
              // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
              res.then(onFulfilledNext, onRejectedNext);
            } else {
              //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
              onFulfilledNext(res);
            }
          }
        } catch (err) {
          // 如果函数执行出错,新的Promise对象的状态为失败
          onRejectedNext(err);
        }
      };
      switch (_status) {
        // 当状态为pending时,将then方法回调函数加入执行队列等待执行
        case PENDING:
          this._fulfilledQueues.push(fulfilled);
          this._rejectedQueues.push(rejected);
          break;
        // 当状态已经改变时,立即执行对应的回调函数
        case FULFILLED:
          fulfilled(_value);
          break;
        case REJECTED:
          rejected(_value);
          break;
      }
    });
  }
catch错误处理
 catch(onRejected) {
    return this.then(undefined, onRejected);
  }
静态调用方法resolve和reject
  static resolve(value) {
    // 如果参数是MyPromise实例,直接返回这个实例
    if (value instanceof MyPromise) return value;
    return new MyPromise((resolve) => resolve(value));
  }
all方法
static all(list) {
    return new MyPromise((resolve, reject) => {
      /**
       * 返回值的集合
       */
      let values = [];
      let count = 0;
      for (let [i, p] of list.entries()) {
        // 数组参数如果不是MyPromise实例,先调用MyPromise.resolve
        this.resolve(p).then(
          (res) => {
            values[i] = res;
            count++;
            // 所有状态都变成fulfilled时返回的MyPromise状态就变成fulfilled
            if (count === list.length) resolve(values);
          },
          (err) => {
            // 有一个被rejected时返回的MyPromise状态就变成rejected
            reject(err);
          }
        );
      }
    });
  }
rece方法
 static race(list) {
    return new MyPromise((resolve, reject) => {
      for (let p of list) {
        // 只要有一个实例率先改变状态,新的MyPromise的状态就跟着改变
        this.resolve(p).then(
          (res) => {
            resolve(res);
          },
          (err) => {
            reject(err);
          }
        );
      }
    });
  }

分析

  1. 当不执行then():执行resolve或者reject,这两个函数相当于无效执行,因为事件队列中没有事件
  2. 当执行then(onFulfilled, onRejected):因为resolve和reject都是异步,所以then会先执行,把onFulfilled, onRejected封装进fulfilled,rejected,中并做一些处理,比如判断是否是函数、函数中如果还有返回的promise,在做一次.then(onFulfilledNext, onRejectedNext)。封装好的fulfilled,rejected放进成功和失败的函数队列中,当调用resolve或者reject时遍历队列依次执行
  3. resolve和reject两个静态方法,用来Promise.resolve(‘成功了’)执行
  4. Promise.all遍历执行所有Promise,如果有一个失败则执行reject()。不要把不同模块放进一个all中执行,导致一个Promise失败,所有的数据都拿不到
  5. Promise.race一个函数执行完毕,其他的不在执行,一般用来对比两种方法,哪一种响应更快
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值