JavaScript基础:手写Promise(2)

在这里插入图片描述

书接上回,本次推文将会继续讲解Promise的开发,以提高异步编程的能力。

一、回顾

上次推文代码回顾:

class MyPromise{
    static PENDING = 'pending';
	static FULFILLED = 'fulfilled';
	static REJECTED = 'rejected';
	constructor(executor){
        this.status = MyPromise.PENDING;
        this.value = null;
        this.callbacks = [];
        try{
            executor(this.resolve.bind(this),this.reject.bind(this));
        } catch{
            this.reject(error);
        }
    }
	resolve(value){
        if(this.status == MyPromise.PENDING){
            this.status = MyPromise.FULFILLED;
            this.value = value;
            this.callbacks.map(callback =>{
            	callback.onFulfilled(value);
        	});
        }
    }
	reject(value){
        if(this.status == MyPromise.PENDING){
            this.status = MyPromise.REJECTED;
            this.value = value;
            this.callbacks.map(callback =>{
            	callback.onRejected(value);
        	});
        }
    }
	
	then(onFulfilled,onRejected) {
    	if(typeof onFulfilled != "function"){
        	onFullfilled = value =>value;
    	}
    	if(typeof onRejected != "function"){
        	onRejected = value => value;
    	}
    	let promise = new MyPromise((resolve,reject) =>{
        	if(this.status == MyPromise.PENDING){
            	this.callbacks.push({
                	onFUlfilled: value =>{
                    	this.parse(onFulfilled(this.value),resolve,reject);
                	},
                	onRejected: value =>{
                    	this.parse(onRejected(this.value),resolve,reject);
                	}
            	});
        	}
        	if(this.status == MyPromise.FULFILLED){
            	setTimeout(()=>{
                	this.parse(onFulfilled(this.value),resolve,reject);
            	});
        	}
        	if(this.status == MyPromise.REJECTED){
            	setTime(()=>{
                	this.parse(onRejected(this.value),resolve,reject);
            	});
        	}
    	});
    	return promise;
	}
	parse(result,resolve,reject){
    	try{
        	if(result instanceof MyPromise){
            	result.then(resolve,reject);
        	}else{
            	resolve(result);
        	}
    	} catch(error){
        	reject(error);
    	}
	}
}

接下来我们实现Promise的静态方法(方法添加到MyPromise类里面)

二、RESOLVE

有时需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。

static resolve(value) {
  return new MyPromise((resolve, reject) => {
    if (value instanceof MyPromise) {
      value.then(resolve, reject);
    } else {
      resolve(value);
    }
  });
}

使用普通值的测试:

MyPromise.resolve("前端收割机!!!!").then(value => {
  console.log(value);
});
// 前端收割机!!!!

使用状态为fulfilledpromise值测试:

MyPromise.resolve(
  new MyPromise(resolve => {
    resolve("前端收割机!!!!");
  })
).then(value => {
  console.log(value);
});
// 前端收割机!!!!

使用状态为rejectedPromise测试

MyPromise.resolve(
  new MyPromise((_, reject) => {
    reject("前端收割机!!!!");
  })
).then(
  value => {
    console.log(value);
  },
  reason => {
    console.log(reason);
  }
);
// 前端收割机!!!!
三、REJECT

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

下面定义Promiserejecte方法

static reject(reason) {
  return new MyPromise((_, reject) => {
    reject(reason);
  });
}

使用测试

MyPromise.reject("rejected").then(null, reason => {
  console.log(reason);
});
// rejected
四、ALL

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all()方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

p的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

下面来实现Promise的all方法

static all(promises) {
  let resolves = [];
  return new MyPromise((resolve, reject) => {
    promises.forEach((promise, index) => {
      promise.then(
        value => {
          resolves.push(value);
          if (resolves.length == promises.length) {
            resolve(resolves);
          }
        },
        reason => {
          reject(reason);
        }
      );
    });
  });
}

来对所有Promise状态为fulfilled的测试:

let p1 = new MyPromise((resolve, reject) => {
  resolve("前端收割机");
});
let p2 = new MyPromise((resolve, reject) => {
  resolve("前端收割机");
});
let promises = MyPromise.all([p1, p2]).then(
  promises => {
    console.log(promises);
  },
  reason => {
    console.log(reason);
  }
);
// ["前端收割机","前端收割机"]

使用我们写的resolve进行测试:

let p1 = MyPromise.resolve("前端收割机1");
let p2 = MyPromise.resolve("前端收割机2");
let promises = HD.all([p1, p2]).then(
  promises => {
    console.log(promises);
  },
  reason => {
    console.log(reason);
  }
);
// ["前端收割机1","前端收割机2"]

其中一个Promise为rejected时的效果:

let p1 = MyPromise.resolve("前端收割机");
let p2 = MyPromise.reject("rejected");
let promises = MyPromise.all([p1, p2]).then(
  promises => {
    console.log(promises);
  },
  reason => {
    console.log(reason);
  }
);
// rejected
五、RACE

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.race()方法的参数与Promise.all()方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理。

下面实现Promise的race方法

static race(promises) {
  return new MyPromise((resolve, reject) => {
    promises.map(promise => {
      promise.then(value => {
        resolve(value);
      });
    });
  });
}

我们来进行测试

let p1 = MyPromise.resolve("前端收割机1");
let p2 = MyPromise.resolve("前端收割机2");
let promises = MyPromise.race([p1, p2]).then(
  promises => {
    console.log(promises);
  },
  reason => {
    console.log(reason);
  }
);
// 前端收割机1

使用延迟Promise后的效果

let p1 = new MyPromise(resolve => {
  setInterval(() => {
    resolve("前端收割机1");
  }, 2000);
});
let p2 = new MyPromise(resolve => {
  setInterval(() => {
    resolve("前端收割机2");
  }, 1000);
});
let promises = MyPromise.race([p1, p2]).then(
  promises => {
    console.log(promises);
  },
  reason => {
    console.log(reason);
  }
);
// 前端收割机2
六、MyPromise整体代码

下面就是这两次推文中手写Promise的整体代码,MyPromise的功能还不能完整模仿Promise的功能,真实的Promise中还具有Promise.try()Promise.any()Promise.allSettled()等静态方法,有兴趣的小伙伴可以自行尝试,这两节推文讲解Promise的开发,主要是提高异步编程的能力,以及对于Promise的理解。

class MyPromise{
    static PENDING = 'pending';
	static FULFILLED = 'fulfilled';
	static REJECTED = 'rejected';
	constructor(executor){
        this.status = MyPromise.PENDING;
        this.value = null;
        this.callbacks = [];
        try{
            executor(this.resolve.bind(this),this.reject.bind(this));
        } catch{
            this.reject(error);
        }
    }
	resolve(value){
        if(this.status == MyPromise.PENDING){
            this.status = MyPromise.FULFILLED;
            this.value = value;
            this.callbacks.map(callback =>{
            	callback.onFulfilled(value);
        	});
        }
    }
	reject(value){
        if(this.status == MyPromise.PENDING){
            this.status = MyPromise.REJECTED;
            this.value = value;
            this.callbacks.map(callback =>{
            	callback.onRejected(value);
        	});
        }
    }
	
	then(onFulfilled,onRejected) {
    	if(typeof onFulfilled != "function"){
        	onFullfilled = value =>value;
    	}
    	if(typeof onRejected != "function"){
        	onRejected = value => value;
    	}
    	let promise = new MyPromise((resolve,reject) =>{
        	if(this.status == MyPromise.PENDING){
            	this.callbacks.push({
                	onFUlfilled: value =>{
                    	this.parse(onFulfilled(this.value),resolve,reject);
                	},
                	onRejected: value =>{
                    	this.parse(onRejected(this.value),resolve,reject);
                	}
            	});
        	}
        	if(this.status == MyPromise.FULFILLED){
            	setTimeout(()=>{
                	this.parse(onFulfilled(this.value),resolve,reject);
            	});
        	}
        	if(this.status == MyPromise.REJECTED){
            	setTime(()=>{
                	this.parse(onRejected(this.value),resolve,reject);
            	});
        	}
    	});
    	return promise;
	}
	parse(result,resolve,reject){
    	try{
        	if(result instanceof MyPromise){
            	result.then(resolve,reject);
        	}else{
            	resolve(result);
        	}
    	} catch(error){
        	reject(error);
    	}
	}

	static resolve(value) {
  		return new MyPromise((resolve, reject) => {
    		if (value instanceof MyPromise) {
      			value.then(resolve, reject);
    		} else {
      			resolve(value);
    		}
  		});
	}
	
	static reject(reason) {
  		return new MyPromise((_, reject) => {
    		reject(reason);
  		});
	}

	static all(promises) {
  		let resolves = [];
  		return new MyPromise((resolve, reject) => {
    		promises.forEach((promise, index) => {
      			promise.then(
        			value => {
          				resolves.push(value);
          				if (resolves.length == promises.length) {
            			resolve(resolves);
          				}
        			},
        			reason => {
          			reject(reason);
        			}
      			);
    		});
  		});
	}
	
	static race(promises) {
  		return new MyPromise((resolve, reject) => {
    		promises.map(promise => {
      			promise.then(value => {
        			resolve(value);
      			});
    		});
  		});
	}
	
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值