前端那些事系列之进阶篇Promise(五)

  1. resolve&reject
  2. throw
  3. then
  4. 定时器
  5. 其他方法(all、ruce)

1) resolve&reject

在这里插入图片描述

  • 执行了resolve,Promise状态会变为fulfilled
  • 执行了reject,Promise状态会变为rejected
  • Promise状态不可逆,第一次成功就永久fulfilled,第一次失败就永久rejected
  • Promise中有throw的话,就相当于报错执行了reject
实现

Promise的初始状态是pending;需要对resolve和reject绑定this,确保reslove和reject的this永远指向当前的new Promise实例,防止随着执行环境的改变而改变。

Promise三种状态
  • pending:等待中,是初始状态;
  • fulfilled:成功状态;
  • rejected:失败状态;

一旦状态从初始状态变为fulfilled或者rejected,那么当前的实例状态就不可再变了

class _Promise(executor){
	constructor(){
		//初始化值
		this.initValue();
		this.initBind();
	}
	initValue(){
		this.PromiseResult=null;
		this.PromiseState='pending';
	}
	initBind(){
		//初始化this
		this.resolve=this.resolve.bind(this);
		this.reject=this.resolve.bind(this);
	}
	resolve(value){
		//state不可变
		if(this.PromiseState!=='pending')return;
		//如果执行resolve,状态变为fulfilled
		this.PromiseState='fulfilled';
		//结果赋给PromiseResult
		this.PromiseResult=value;
	}
	reject(reason){
		//state不可变
		if(this.PromiseState!=='pending')return;
		//如果执行reject,状态变为rejected
		this.PromiseState='rejected';
		this.PromiseResult=reason;
	}
}

2)throw

Promise中有throw,就相当于执行了reject,在构造方法中需要新增try catch部分

	constructor(executor){
		this.initValue();
		this.initBind();
		try{
			//执行传入函数
			executor(this.resolve,this.reject);
		}catch(e){
			this.reject(e);
		}
	}

3) then

  • then接受两个回调,一个成功回调,一个失败回调;
  • 当状态为fulfilled执行成功回调,为rejected执行失败回调;
  • 如果reslove或者reject在定时器里,那么定时器结束后再执行then;
  • then支持链式调用,下一次then内的数值会受到上一次then内返回值的影响;
实现
	then(onFulfilled, onRejected) {
		// 接收两个回调 onFulfilled, onRejected
		// 参数校验,确保⼀定是函数
		onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
		onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
		if (this.PromiseState === 'fulfilled') {
			// 如果当前为成功状态,执⾏第⼀个回调
			onFulfilled(this.PromiseResult)
		} else if (this.PromiseState === 'rejected') {
			// 如果当前为失败状态,执⾏第⼆哥回调
			onRejected(this.PromiseResult)
		}
	}

4) 定时器

思路 先将then里的回调保存起来,等到定时器结束,执行了resolve和reject后,再去判断状态,并且判断要去执行保存的哪一个回调。

class _Promise {
	// 构造⽅法
	constructor(executor) {
		// 初始化值
		this.initValue();
		// 初始化this指向
		this.initBind();
		try {
			// 执⾏传进来的函数
			executor(this.resolve, this.reject)
		} catch (e) {
			// 捕捉到错误直接执⾏reject
			this.reject(e)
		}
	}
	initBind() {
		// 初始化this
		this.resolve = this.resolve.bind(this)
		this.reject = this.reject.bind(this)
	}
	initValue() {
		// 初始化值
		this.PromiseResult = null // 终值
		this.PromiseState = 'pending' // 状态
		this.onFulfilledCallbacks = [] // 保存成功回调
		this.onRejectedCallbacks = [] // 保存失败回调
	}
	resolve(value) {
		// state是不可变的
		if (this.PromiseState !== 'pending') return
		// 如果执⾏resolve,状态变为fulfilled
		this.PromiseState = 'fulfilled'
		// 终值为传进来的值
		this.PromiseResult = value
		// 执⾏保存的成功回调
		while (this.onFulfilledCallbacks.length) {
			this.onFulfilledCallbacks.shift()(this.PromiseResult)
		}
	}
	reject(reason) {// state是不可变的
		if (this.PromiseState !== 'pending') return
		// 如果执⾏reject,状态变为rejected
		this.PromiseState = 'rejected'
		// 终值为传进来的reason
		this.PromiseResult = reason
		// 执⾏保存的失败回调
		while (this.onRejectedCallbacks.length) {
			this.onRejectedCallbacks.shift()(this.PromiseResult)
		}
	}
	then(onFulfilled, onRejected) {
		// 接收两个回调 onFulfilled, onRejected
		// 参数校验,确保⼀定是函数
		onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val=> val;
		onRejected = typeof onRejected === 'function' ? onRejected : reason=> { throw reason };
		if (this.PromiseState === 'fulfilled') {
			// 如果当前为成功状态,执⾏第⼀个回调
			onFulfilled(this.PromiseResult)
		} else if (this.PromiseState === 'rejected') {
			// 如果当前为失败状态,执⾏第⼆哥回调
			onRejected(this.PromiseResult)
		} else if (this.PromiseState === 'pending') {
			// 如果状态为待定状态,暂时保存两个回调
			this.onFulfilledCallbacks.push(onFulfilled.bind(this))
			this.onRejectedCallbacks.push(onRejected.bind(this))
		}
	}
}

5)其它

  • all
    接受一个Promise数组,数组中有非Promise项,则当作此项成功;
    如果所有Promise都成功,则返回成功结果数组;
    如果有一个失败,则返回这个失败结果
    static all(promises){
    	const result=[];
    	let count=0;
    	return new _Promise((resolve,reject)=>{
    		const addData=(index,value)=>{
    			result[index]=value;
    			count++;
    			if(count==promises.length)resolve(result);
    		}
    		promise.forEach((promise,index)=>{
    			if(promise instanceof _Promise){
    				promise.then(res=>{
    					addData(index,res)
    				},err=>reject(err));
    			}else {
    				addData(index,promise)
    			}
    		})
    	})
    }
    
  • race
    接受一个Promise数组,数组中有非Promise项,则当此项成功;
    哪个Promise最快得到结果,就返回那个结果,无论成功失败
static race(promises) {
	return new _Promise((resolve, reject) => {
		promises.forEach(promise => {
		if (promise instanceof _Promise) {
			promise.then(res => {
				resolve(res)
			}, err => {
				reject(err)
			})
		} else {
			resolve(promise)
		}
		})
	})
}
  • any
    接收⼀个Promise数组,数组中如有⾮Promise项,则此项当做成功;
    如果有⼀个Promise成功,则返回这个成功结果;
    如果所有Promise都失败,则报错;
static any(promises){
	return new _Promise((resolve,reject)=>{
		let count=0;
		promises.forEach((promise)=>{
			promise.then(val=>{
				resolve(val);
			},err=>{
				count++;
				if(count===promises.length){
					reject(new AggregateError('All promises were rejected'))	
				}
					
			})
		})
	})
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值