利用JS实现Promise对象
首先新建类MyPromise
,并声明静态常量PENDING
、FUFILLED
、REJECTED
表示promise的状态,exector
函数带有resolve
、reject
两个函数参数,MyPromise
执行构造函数时立即调用;调用resolve
、reject
函数时,分别将promise状态改为fulfilled
、rejected
。
代码如下:
MyPromise
类:
class MyPromise{
static PENDING = 'pending';
static FUFILLED = 'fufilled';
static REJECTED = 'rejected';
constructor(executor){
this.status = MyPromise.PENDING;
this.value = null;
executor(this.resolve.bind(this), this.reject.bind(this));
}
resolve(value){
this.status = MyPromise.FUFILLED;
this.value = value;
}
reject(reason){
this.status = MyPromise.REJECTED;
this.value = reason;
}
}
调用MyPromise
:
let mypromise = new MyPromise((resolve, reject) => {
resolve("已解决");
reject("拒绝");
});
console.log(mypromise)
此时,在mypromise
实例中,promise的状态在改为成功后,依旧可以改为失败
只需在resolve()
、reject()
中分别添加状态判断即可
resolve(value){
if(this.status == MyPromise.PENDING){
this.status = MyPromise.FUFILLED;
this.value = value;
}
}
reject(reason){
if(this.status == MyPromise.PENDING){
this.status = MyPromise.REJECTED;
this.value = reason;
}
在promise中,如果在executor
函数中抛出一个错误,promise的状态也应是rejected
,返回值被忽略。将构造函数中的executor()
函数加上异常捕获,并修改状态
executor(this.resolve.bind(this), this.reject.bind(this));
//改为:
try {
executor(this.resolve.bind(this), this.reject.bind(this));
}catch(error) {
this.reject(error);
}
接着实现then
函数,在MyPromise
函数中添加then
方法
then(onFulfilled, onRejected){
if(typeof onFulfilled !== "function"){
onFulfilled = () => {};
}
if(typeof onRejected !== "function"){
onRejected = () => {};
}
//两个if防止 当 .then() 中只写处理成功状态或失败状态函数时报错
if(this.status == MyPromise.FUFILLED){
onFulfilled(this.value);
}
if(this.status == MyPromise.REJECTED){
onRejected(this.value)
}
//两个if 当promise中不处理时,即状态为pending时,不执行
}
加入异常捕获,放入setTimeout()
中,实现异步
if(this.status == MyPromise.FUFILLED){
onFulfilled(this.value);
}
if(this.status == MyPromise.REJECTED){
onRejected(this.value)
}
//改后
if(this.status == MyPromise.FUFILLED){
setTimeout( () => { //实现同步代码比promise中的先执行
try {
onFulfilled(this.value);
} catch (error) {
onRejected(error);
}
});
}
if(this.status == MyPromise.REJECTED){
setTimeout( () =>{
try {
onRejected(this.value);
} catch (error) {
onRejected(error);
}
});
}
当调用如下时
let mypromise = new MyPromise((resolve, reject) => {
setTimeout( () => {
resolve("已解决");
},1000);
// reject("拒绝");
}).then(value => console.log(value), reason => console.log(reason));
此时,由于同步代码执行完毕后,MyPromise
的状态延迟1000毫秒改变,因此执行then()
函数时,依旧为pengding
状态,此时不会执行onFulfilled
和onRejected
函数,由于顺序执行,定时器到时之后promise状态改变,但无法正常输出。
此时在MyPromise
类的构造函数中加入this.callbacks = [];
,用于盛放onFulfilled
和onRejected
函数,分别在resolve()
和reject()
调用,即可实现
//constructor中加入
this.callbacks = [];
//resolve()和reject()中分别加入
this.callbacks.map(callback => {
callback.onFulfilled(value);
});
this.callbacks.map(callback => {
callback.onRejected(value);
});
//在then函数中加入状态判断
if (this.status == MyPromise.PENDING){
this.callbacks.push({
onFulfilled,
onRejected
});
}
经过上述改动后,调用时,在resolve("已解决");
后面加上语句console.log("我先输出");
,正常输出顺序为“我先输出”、“已解决”,但此时相反
将上边resolve()
和reject()
中新增的函数分别放进计时器即可
setTimeout(() => {
this.callbacks.map(callback => {
callback.onFulfilled(value);
});
});
此时还不能进行链式操作,将then()
方法中的状态判断及onFulfilled
和onRejected
函数整体刚入一个新的MyPromise
中返回并将onFulfilled
和onRejected
函数的返回值分别给resolve()
和reject()
传给下一层then
即可实现链式操作
return new MyPromise((resolve,reject) =>{
if (this.status == MyPromise.PENDING){
this.callbacks.push({
onFulfilled: value => {
try{
let result = onFulfilled(value);
resolve(result);
} catch(error) {
reject(error);
}
},
onRejected: value => {
try {
let result = onRejected(value);
resolve(result);
} catch (error) {
reject(error);
}
}
});
}
if(this.status == MyPromise.FUFILLED){
setTimeout( () => {
try {
let result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
});
}
if(this.status == MyPromise.REJECTED){
setTimeout( () =>{
try {
let result = onRejected(this.value);
resolve(result);
} catch (error) {
reject(error);
}
});
}
})
除此之外,原生then
还有穿透性,即不对某一层then()
进行任何处理,下一层照常可以进行处理
//只需要在此处 给他返回当前的value值即可穿透传递
if(typeof onFulfilled !== "function"){
onFulfilled = () => this.value;
}
if(typeof onRejected !== "function"){
onRejected = () => this.value;
}
实现promise.all()
函数
static all(promises){
const values = [];
return new MyPromise((resolve,reject) => {
promises.forEach(promise => {
promise.then(value => {
values.push(value);
if(values.length == promises.length){
resolve(values)
}
}, reason => {
reject(reason);
});
});
});
}
实现promise.race()
方法
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(value => {
resolve(value);
}, reason => {
reject(reason);
})
});
});
}