eventLoop那里Promise对象的产生的回调应该放到微队列中,但是不知道该怎么实现,所以放到了宏队列中(有大佬知道的话劳请告知,哪里看不懂可以把问题放到评论区或者私信我,看到就回)
const MyPromise = (() => {
const PENDING = 'pending',
RESOLVED = 'resolved',
REJECTED = 'rejected',
MyPromiseStatus = Symbol('MyPromiseStatus'),
MyPromiseValue = Symbol('MyPromiseValue'),
changeStatus = Symbol('changeStatus'),
thenables = Symbol('thenable'), //thenable 业队列
catchables = Symbol('catchable'), /catchable作业队列
subsequentHandle = Symbol('subsequentHandle')//后续处理函数的封装
linkPromise = Symbol('linkPromise');
return class {
/**
* 将Promise从未决状态推向已决状态时,改变状的函数
* @param {*} data 状态数据
* @param {*} immediatelyStatus 推向已决状态应该所处的状态
* @param {*} targetStatus 将要推向的状态
* @returns
*/
[changeStatus](value, targetStatus, queue) {
// 如果状态是pending
if (this[MyPromiseStatus] !== PENDING) {
return;
}
// 状态是已决态
this[MyPromiseStatus] = targetStatus;
this[MyPromiseValue] = value;
// 遍历执行作业队列中的处理函数
queue.forEach(handle => handle(thi[MyPromiseValue]))
}
constructor(untreated) {
// untreated表示未决阶段的处理函数
this[MyPromiseStatus] = PENDING;
this[MyPromiseValue] = undefined;
this[thenables] = [];
this[catchables] = [];
const resolve = (data) => {
this[changeStatus](data, RESOLVED,this[thenables]);
}
const reject = (reason) => {
this[changeStatus](reason, REJECTED,this[catchables]);
// 拒绝的话打印错误消息,Promise直接出的错误
// console.error(new Error(reason));
}
// 捕获到错误后将错误数据传递作为rejecte的状态数据
try {
// 这里untreated是一个形参,他是传一带有两个函数作为参
//数的函数,第一个参数是resolve, 第个参数是reject,这里将他写全调用即可
untreated(resolve, reject);
}
catch (err) {
// 捕获到初始化函数执行中的错误后将误信息设置为状态数据,并改变状态
this[MyPromiseValue] = err;
this[MyPromiseStatus] = REJECTED;
}
}
/**
* 针对then和catch写的封装函数 handlerthenable或者catchable
* @param {*} handler catchable或者thenable理函数
* @param {*} immediatelyStatus
* @param {*} queue
*/
[subsequentHandle](handler,immediatelyStatus, queue) {
if (typeof handler !== 'function') {
return;
}
if (this[MyPromiseStatus] ===immediatelyStatus) {
// 直接执行函数
setTimeout(() => {
handler(this[MyPromiseValue]);
//注意这里函数如果直接执行的话,
//会将这个参数传递给立即执行函数data
}, 0)
} else {
queue.push(handler);
//注意这里的函数如果不立即执行的话,会改变状态那里遍历执行
}
}
/**
* 返回一个后续处理函数返回的Promise对象
* @param {*} thenable
* @param {*} catchable
* @returns
*/
[linkPromise](thenable, catchable) {
/**
*
* @param {*} data 改变状态函数那里立即行传进来的实参
* @param {*} handle 当前Promise对象的后处理函数
* @param {*} resolve 返回的新的Promiseresolve
* @param {*} reject 返回的新的Promisereject
*/
function exec(data, handle, resolve,reject) {
try {
// handle是当前Promise 后续处理数
const result = handle(data);
//立即执行的话需要知道当前的data,
//这个data就是异步立即执行那里传来的实参
if (result instanceof MyPromise) {
result.then(data => {
resolve(data);
})
} else {
resolve(result);
}
} catch (error) {
reject(error)
}
}
return new MyPromise((resolve, reject) =>{
// 返回的新的promise对象是当thenale数执行后返回,并且该Promise的状态
//数据为thenable函数的返回值,也就是什么时候返回新的对象,是当
//catchable执行之后在返回
this[subsequentHandle]((data) => {
// 该promise对象没有添加thenable 函数,回的全新的Promise对象的状态数据应
//该是该promise对象的状态数据,而且此时态(该promise状态已经是resolved
//了,返回的全新的Promise对象的状态应该是thenable)应该改变
if (typeof thenable !=='function') {
resolve(data);//调用这个函数时候状态会自动更改
return;//防止执行exec函数,致状态无法改变
}
exec(data, thenable, resolve,reject);
}, RESOLVED, this[thenables]);
this[subsequentHandle]((reason) => {
if (typeof catchable !=='function') {
reject(reason);//调用这个函的时候状态会自动更改
return;//防止执行exec函数,致状态无法改变
}
exec(reason, catchable, resolve,reject);
}, REJECTED, this[catchables]);
})
}
then(thenable, catchable) {
// 这里面的代码是 异步代码,如果这里Promie状态是RESOLVED,
//立即执行,如果是pending,则加入到queue中
// this[subsequentHandle](thenable,RESOLVED, this[thenables]);
// if (typeof catchable === 'function') {
// this[subsequentHandle](catchable,REJECTED, this[catchables]);
// }
return this[linkPromise](thenable,catchable);
}
catch(catchable) {
// this[subsequentHandle](catchable,REJECTED, this[catchables]);
return this[linkPromise](undefined,catchable);
}
static all(pros) {
return new MyPromise((resolve, reject) =>{
try {
const results = pros.map(p => {
const obj = {
result: undefined,
isResolve: false
}
p.then(data => {
obj.result = data;
obj.isResolve = true;
const unResolve =results.filter((item) =>!item.isResolve);
if (unResolve.length ===0) {
resolve(results.map(item => item.result);
}
}, reason => {
reject(reason);
})
return obj;
})
} catch (error) {
reject(error);
}
})
}
static race(pros) {
return new MyPromise((resolve, reject) =>{
try {
pros.forEach((item) => {
// item是一个Promise,其中有个item resolve,
item.then(data => {
resolve(data);
}, reason => {
reject(reason);
})
})
} catch (error) {
reject(error);
}
})
}
static resolve(data) {
return new MyPromise((resolve) => {
resolve(data);
})
}
static reject(reason) {
return new MyPromise((resolve, reject) =>{
reject(reason);
})
}
}
})()