首先我们需要先规定一下Promise的基本规定:
•Promise存在三个状态(state)pending、fulfilled、rejected
•pending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态)
•成功时,不可转为其他状态,且必须有一个不可改变的值(value)
•失败时,不可转为其他状态,且必须有一个不可改变的原因(reason)
• new Promise((resolve, reject)=>{resolve(value)}) resolve为成功,接收参数value,状态改变为fulfilled,不可再次改变。
• new Promise((resolve, reject)=>{reject(reason)}) reject为失败,接收参数reason,状态改变为rejected,不可再次改变。
•若是executor函数报错 直接执行reject();
class MyPromise{
constructor(executor){
//首先先定义状态,resolve的参数,reject的参数
this.state='pending';
this.value=undefined;
this.reason=undefined;
let resolve=(value)=>{
//在此判断是否为pending状态,是为了确保pending状态一旦转化为fulfilled就不能在改变了
if(this.state=='pending'){
this.state='fulfilled';
this.value=value;
}
}
let reject=(reason)=>{
if(this.state=='pending'){
this.state='rejected';
this.reason=reason;
}
}
try{
executor(resolve,reject)
}catch(err){
reject(err)
}
}
}
then方法
• Promise中的then方法有两个参数:onFulfilled,onRejected,成功有成功的值,失败有失败的原因
• 当状态state为fulfilled,则执行onFulfilled,传入this.value。当状态state为rejected,则执行onRejected,传入this.value
class MyPromise{
constructor(executor){...}
then(onFulfilled,onRejected){
if(this.state=='fulfilled'){
onFulfilled(this.value)
}
if(this.state=='rejected'){
onRejected(this.reason)
}
}
}
解决异步实现
let p1=new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功了')
},100)
})
p1.then((value)=>{
console.log(value)
},(err)=>{
console.log(err)
})
• 当resolve在setTimeout中时,then中的state一直是pending状态,因此在then中根本就没有执行resolve,所以我们就需要在then调用的时候,state为pending的时候,将成功和失败存到各自的数组,一旦reject或者resolve,就调用它们(发布订阅模式)
• 由于一个promise可以有多个then,所以存在同一个数组内。
class MyPromise{
constructor(executor){
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
// 成功存放的数组
this.onResolvedCallbacks = [];
// 失败存放法数组
this.onRejectedCallbacks = [];
let resolve = value => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// 一旦resolve执行,调用成功数组的函数
this.onResolvedCallbacks.forEach(fn=>fn());
}
};
let reject = reason => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
// 一旦reject执行,调用失败数组的函数
this.onRejectedCallbacks.forEach(fn=>fn());
}
};
try{
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled,onRejected) {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
};
if (this.state === 'rejected') {
onRejected(this.reason);
};
// 当状态state为pending时
if (this.state === 'pending') {
// onFulfilled传入到成功数组
this.onResolvedCallbacks.push(()=>{
onFulfilled(this.value);
})
// onRejected传入到失败数组
this.onRejectedCallbacks.push(()=>{
onRejected(this.value);
})
}
}
}
let p1=new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功了')
},100)
})
p1.then((value)=>{
console.log(value) //'成功了'
},(err)=>{
console.log(err)
})