手写promise原理
话不多说,直接上代码。
//第一步:控制状态的变化
// 1.未决阶段执行的函数
// 2.状态更改一次后不能再更改
// 3.抛出错误用try catch
//第二步:实现后续的处理
//thenable--resolved catchable--rejected
// then方法 加到队列里面去 已经是resolved则立即执行,否则加到队列里去
//第三步:串联promise,
//在新的promise对象里面让thenable catchable执行并记录返回的数据
const MyPromise = (() => {
const pending = "pending",
resolved = "resolved",
rejected = "rejected",
PromiseValue = Symbol("PromiseValue"),//状态数据
PromiseStatus = Symbol("PromiseStatus"),//当前状态
changeStatus = Symbol("changeStatus"),//改变状态的函数
thenables = Symbol("thenables"),//成功的队列
catchables = Symbol("catchables"),//失败的队列
settleHandler = Symbol("settleHandler"),//后续处理的函数
linkPromise = Symbol("linkPromise");//返回新的promise
return class MyPromise {
/**
*
* @param {*} newStatus
* @param {*} newValue
*/
[changeStatus](newStatus, newValue, queue) {
if (this[PromiseStatus] !== pending) {
//状态无法变更
return;
}
this[PromiseStatus] = newStatus;
this[PromiseValue] = newValue;
//执行相应队列中的函数
queue.forEach(handler => {
handler(newValue);
});
}
/**
* 后续处理的函数
* @param {*} handler
* @param {*} status
* @param {*} queue
*/
[settleHandler](handler, status, queue) {
if (this[PromiseStatus] === status) {
setTimeout(() => {
handler(this[PromiseValue]);
}, 0)
} else {
queue.push(handler);
}
}
[linkPromise](thenable, catchable) {
return new MyPromise((resolve, reject) => {
this[settleHandler](data => {
try {
const result = thenable(data);//得到当前promise的处理结果
if (result instanceof MyPromise) {
result.then(d => {
resolve(d);
}, err => {
reject(err);
})
} else {
resolve(result);
}
} catch (err) {
reject(err)
}
}, resolved, this[thenables])
this[settleHandler](reason => {
try {
const result = catchable(reason);//得到当前promise的处理结果
if (result instanceof MyPromise) {
result.then(d => {
resolve(d);
}, err => {
reject(err);
})
} else {
resolve(result);
}
} catch (err) {
reject(err)
}
}, rejected, this[catchables])
})
}
/**
*
* @param {*} executor 未决阶段下的处理函数
*/
constructor(executor) {
this[PromiseStatus] = pending;
this[PromiseValue] = undefined;
this[thenables] = [];
this[catchables] = [];
const resolve = data => {//写箭头函数 ,避免this指向出错
this[changeStatus](resolved, data, this[thenables]);//在状态改变的时候加入到对应的队列
}
const reject = reason => {
this[changeStatus](rejected, reason, this[catchables]);
}
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(thenable, catchable) {
// this[settleHandler](thenable,resolved,this[thenables]);
// this.catch(catchable);
return this[linkPromise](thenable, catchable);
}
catch(catchable) {
// this[settleHandler](catchable,rejected,this[catchables]);
return this[linkPromise](undefined, catchable);
}
static all(proms) {//所有的promise全部完成之后就完成,一个有错误就错误
return new MyPromise((resolve,reject)=>{
const results = proms.map(p=>{
const obj = {
result:undefined,
isResolved:false
}
p.then(data=>{
obj.result = data;
obj.isResolved = true;
//判断是否全部完成
const unResolved = results.filter(r=>!r.isResolved);
if(unResolved.length === 0){
//全部完成
resolve(result.map(r=>r.result));
}
},reason=>{
reject(reason);
})
return obj;
})
})
}
static race(proms){
return new MyPromise((resolve,reject)=>{
proms.forEach(p=>{
p.then(data=>{//有一个完成就完成
resolve(data);
},err=>{//有一个失败就失败
reject(err);
})
})
})
}
static resolve(data) {
if (data instanceof MyPromise) {
return data;
} else {
return new MyPromise(resolve => {
resolve(data);
})
}
}
static reject(reason) {
return new MyPromise((resolve,reject) => {
reject(reason);
})
}
}
})()