一. Promise 实现的关键点:
1.首先是关于Promise三个状态的问题---
Promise共有三个状态,分别是:
1. pending状态;简单来说,即还未做出决定(接受或者拒绝)的状态,
根据实际场景的需求,最终会变成接受或拒绝的状态,并且不可修改。
2. resolved状态;即已经做出决定,表示接受的状态,且状态不可更改。
3. rejected状态;即已经做出决定,表示拒绝的状态,且状态不可更改。
**需要通过以上规则去实现Promise的构造函数**
2.除了状态之后,另一个就是链式调用的实现---
解决链式调用的两个关键点:
(a)调用then方法必须满足thenable形式的条件:
假设x满足thenable条件有以下代码:
x!==null&&(typeof x === 'object'|| typeof x ==='function')&&typeof x.then ==='function'
(b)实现链式调用传参的关键代码:
var x = onResolved(this.data);
二. 完整代码实现
class MyPromise{
/**
* 构造函数设计思路:Promise有三个状态 pending[该状态可以理解为待定状态,它可能会变成resolved也可能会变成rejected]、
* resolved[该状态一经确定后不可改变,并接受一个value值]和rejected[该状态一经确定后不可改变,并接受一个reason]
* Promise构造函数需要传入一个参数fn(resolve,reject)
* @param {*} fn
*/
constructor(fn){
this.data = undefined;
this.status = 'pending';
this.onResolvedCallback = [];
this.onRejectedCallback = [];
let resolve = (value)=>{
if(this.status === 'pending'){
this.status = 'resolved';
this.data = value;
this.onResolvedCallback.forEach((item)=>{
item(value);
})
}
};
let reject = (reason)=>{
if(this.status==='pending'){
this.status='rejected';
this.data = reason;
this.onRejectedCallback.forEach((item)=>{
item(value);
})
}
}
try{
fn(resolve,reject);
}catch(e){
reject(e);
}
}
/**
* @param {*} onResolved
* @param {*} onRejected
* @returns
*/
then(onResolved,onRejected){
onResolved = typeof onResolved === 'function'?onResolved:function(value){ return value}; //onResolved和onRejected必须是函数 如果不是函数 会自动忽略并取出值
onRejected = typeof onRejected === 'function'?onRejected:function(reason){ return reason};
if(this.status==='resolved'){
return new MyPromise((resolve,reject)=>{
try{
var x = onResolved(this.data);
resolvePromise(this,x,resolve,reject);
}catch(e){
reject(e)
}
});
}
if(this.status==='rejected'){
return new MyPromise((resolve,reject)=>{
try{
var x = onRejected(this.data);
resolvePromise(this,x,resolve,reject);
}catch(e){
reject(e);
}
});
}
//pending状态下需要将函数先放入回调数组里面暂存 当Promise状态为resolved或者rejected的时候再执行
if(this.status==='pending'){
return new MyPromise((resolve,reject)=>{
this.onResolvedCallback.push(function(value){
try{
var x = onResolved(value);
resolvePromise(this,x,resolve,reject);
}catch(e){
reject(e);
}
});
this.onRejectedCallback.push(function(reason){
try{
var x = onRejected(reason);
resolvePromise(this,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
}
}
}
function resolvePromise(promise2,x,resolve,reject){
let throwFlag = false; //一个Promise最终只能有一种状态 这里使用flag作为标识 谁先执行就是谁的状态
if(promise2 === x){
reject(new Error('TypeError'));
}
if(x instanceof MyPromise){
if(x.status === 'pending'){
x.then((value)=>{
resolvePromise(x,value,resolve,reject);
},reject);
}else{
x.then(resolve,reject);
}
return
}
//以下判断语句是判断是否是thenable形式
if(x!==null&&(typeof x === 'object'|| typeof x ==='function')&&typeof x.then === 'function'){
try{
x.then((v)=>{
if(throwFlag) return
throwFlag = true;
resolvePromise(x,v,resolve,reject);
},(r)=>{
if(throwFlag) return
throwFlag = true;
reject(r);
})
}catch(e){
if(throwFlag) return
throwFlag = true;
reject(e);
}
}else{
resolve(x)
}
}