手写Promise
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
//创建微队列
function runMicroTask(callback) {
//判断node环境 process.nextTick是node的微队列
if (process && process.nextTick) {
process.nextTick(callback); //node环境的微队列
} else if (MutationObserver) {
//MutationObserver 浏览器微队列
const p = document.createElement("p"); //创建p标签
const observer = new MutationObserver(callback); //放入微队列
observer.observe(p, {
childList: true, //观察内部发送的变化
});
p.innerHTML = "1";
} else {
setTimeout(callback, 0); //等待0秒好执行
}
}
//判断一个数据是否是Promise对象
function isPromise(obj) {
return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}
class MyPromise {
constructor(executor) {
this._state = PENDING; //状态
this._value = undefined; //数据
this._handlers = []; //处理函数的队列
try {
executor(this._resolve.bind(this), this._reject.bind(this)); //成功
} catch (error) {
this.reject(error); //失败
}
}
/*
向处理函数中添加一个函数,executor 添加的函数 state 状态 ,resolve then返回的promise成功 reject 让then返回的promise失败
目的是:要是想要让then执行,那么一定是有成功/失败的状态下才会去执行then,所以这时候then就会进入微队列等待状态的完成!所以需要给then编写一个微队列
但是这时候遇到一个问题:添加到微队列后,他也不知道任务的状态是成功的还是失败的,所以需要编写_pushHandlers的方法
executor: [Function: A1],
state: 'fulfilled',
resolve: [Function: bound _resolve],
reject: [Function: bound _reject]
*/
_pushHandlers(executor, state, resolve, reject) {
this._handlers.push({
executor,
state,
resolve,
reject,
});
}
/*
根据实际清空,执行队列
*/
_runHandlers() {
if (this._state === PENDING) {
//目前任务还是挂起
return;
}
//执行一个队列,删除一个队列
while (this._handlers[0]) {
const handler = this._handlers[0];
this._runHandler(handler);
this._handlers.shift();
}
}
// 处理一个handlers
_runHandler({ executor, state, resolve, reject }) {
//放入微队列
runMicroTask(() => {
if (this._state !== state) {
//当前状态如果为失败= rejected !== 微服务里面的state进行比较 不等于则不加入微队列
//状态不一致,不处理,不加入微队列
return;
}
//不是函数的情况
if (typeof executor !== "function") {
//三目运算符:当this._state=通过,则执行resolve(值),否则执行reject(值)
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
try {
const result = executor(this._value); //将微队列的executor的函数名进行赋值
if (isPromise(result)) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
//console.log(this._state)
// console.log(handler,'测试')
});
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 将then里面的数据放到微队列,等待状态完成后执行
this._pushHandlers(onFulfilled, FULFILLED, resolve, reject); //成功的
this._pushHandlers(onRejected, REJECTED, resolve, reject); //失败的
this._runHandlers(); //重新执行队列
});
}
//处理失败的场景
catch(onRejected) {
return this.then(null, onRejected);
}
//无论失败还是成功都会执行该函数
finally(onSettled) {
return this.then(
(data) => {
onSettled();
return data;
},
(reason) => {
onSettled();
return reason;
}
);
}
_changeState(newState, value) {
if (this._state != PENDING) {
//要是当前start不是挂起状态,说明已经执行了,那么就return,不在执行
return;
}
this._state = newState;
this._value = value;
this._runHandlers(); //重新执行
}
// 成功的方法
_resolve(data) {
//状态和值
this._changeState(FULFILLED, data);
}
//失败的方法
_reject(fail) {
this._changeState(REJECTED, fail);
}
/* 返回已完成的promise;特殊情况:
1.传递的data本身就是es6的promise对象
2.传递的data是promiseLike(promise A+规范),返回新的promise,状态和其保持一致
*/
//成功的 编写静态的
static resolve(data) {
if (data instanceof MyPromise) {
return data;
}
return new MyPromise((resolve, reject) => {
if (isPromise(data)) {
data.then(resolve, reject);
} else {
resolve(data);
}
});
}
//失败的 编写静态
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
/*
Promise迭代器,包含多个Promise
全部Promise成功,则返回Promise成功,数据为所有Promise成功的数据,并且顺序是按照传入的顺序排列
只要有一个Promise失败,则返回的Promise失败,原因是第一个失败的Promise的原因
*/
static all(proms) {
return new MyPromise((resolve, reject) => {
try {
const result = [];
let count = 0; //promise总数
let fulfilledCount = 0; //已完成的数量
for (const p of proms) {
let i = count;
count++;
MyPromise.resolve(p).then((data) => {
fulfilledCount++;
result[i] = data;
if (fulfilledCount === count) {
//当前最后一个Promise完成
resolve(result);
}
}, reject);
}
if (count === 0) {
resolve(result);
}
} catch (error) {
reject(error);
}
});
}
/*
等待所有promise有结果之后
该方法返回的promise完成
并且按照顺序将所有结果汇总
*/
static allSettled(proms){
const ps = [];
for(const p of proms){
ps.push(
MyPromise.resolve(p).then(
(value) =>({
status:FULFILLED,
value
}),
(reason)=>({
status:REJECTED,
reason
})
)
)
}
return MyPromise.all(ps)
}
//返回的Promise与第一个有结果的一致
static race(proms){
return new MyPromise((resolve,reject)=>{
for(const p of proms){
MyPromise.resolve(p).then(resolve,reject)
}
})
}
}
//两个参数,在class类里面使用该参数
const pro = new MyPromise((resolve, reject) => {
setTimeout(()=>{
reject(1);
},1)
});
//互操作 自己写的Promise 和官方写的promise可以互相操作
// pro
// .then((data)=>{
// console.log(data);//1
// return new Promise((resolve)=>{
// resolve(2)
// })
// })
// .then((data)=>{
// console.log(data);//2
// })
// const pro2 = pro.finally((d)=>{
// console.log('finally',d);
// throw 123
// })
// setTimeout(()=>console.log(pro2))
// MyPromise.all([pro]).then(
// (data) => {
// console.log("成功", data);
// },
// (reason) => {
// console.log("失败", reason);
// }
// );
// const pro1 = MyPromise.allSettled([
// pro,
// MyPromise.resolve(2),
// MyPromise.resolve(3),
// MyPromise.resolve(4),
// 5
// ])
// pro1.then((result)=>{
// console.log(result)
// })
const pro2 = new MyPromise((resolve, reject) => {
setTimeout(()=>{
resolve(1);
},10)
});
const pro1 = MyPromise.race([pro,pro2]);
pro1.then(
(data)=>{
console.log('成功',data)
},
(reason)=>{
console.log('失败',reason)
}
)
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
//创建微队列
function runMicroTask(callback) {
//判断node环境 process.nextTick是node的微队列
if (process && process.nextTick) {
process.nextTick(callback); //node环境的微队列
} else if (MutationObserver) {
//MutationObserver 浏览器微队列
const p = document.createElement("p"); //创建p标签
const observer = new MutationObserver(callback); //放入微队列
observer.observe(p, {
childList: true, //观察内部发送的变化
});
p.innerHTML = "1";
} else {
setTimeout(callback, 0); //等待0秒好执行
}
}
//判断一个数据是否是Promise对象
function isPromise(obj) {
return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}
class MyPromise {
constructor(executor) {
this._state = PENDING; //状态
this._value = undefined; //数据
this._handlers = []; //处理函数的队列
try {
executor(this._resolve.bind(this), this._reject.bind(this)); //成功
} catch (error) {
this.reject(error); //失败
}
}
/*
向处理函数中添加一个函数,executor 添加的函数 state 状态 ,resolve then返回的promise成功 reject 让then返回的promise失败
目的是:要是想要让then执行,那么一定是有成功/失败的状态下才会去执行then,所以这时候then就会进入微队列等待状态的完成!所以需要给then编写一个微队列
但是这时候遇到一个问题:添加到微队列后,他也不知道任务的状态是成功的还是失败的,所以需要编写_pushHandlers的方法
executor: [Function: A1],
state: 'fulfilled',
resolve: [Function: bound _resolve],
reject: [Function: bound _reject]
*/
_pushHandlers(executor, state, resolve, reject) {
this._handlers.push({
executor,
state,
resolve,
reject,
});
}
/*
根据实际清空,执行队列
*/
_runHandlers() {
if (this._state === PENDING) {
//目前任务还是挂起
return;
}
//执行一个队列,删除一个队列
while (this._handlers[0]) {
const handler = this._handlers[0];
this._runHandler(handler);
this._handlers.shift();
}
}
// 处理一个handlers
_runHandler({ executor, state, resolve, reject }) {
//放入微队列
runMicroTask(() => {
if (this._state !== state) {
//当前状态如果为失败= rejected !== 微服务里面的state进行比较 不等于则不加入微队列
//状态不一致,不处理,不加入微队列
return;
}
//不是函数的情况
if (typeof executor !== "function") {
//三目运算符:当this._state=通过,则执行resolve(值),否则执行reject(值)
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
try {
const result = executor(this._value); //将微队列的executor的函数名进行赋值
if (isPromise(result)) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
//console.log(this._state)
// console.log(handler,'测试')
});
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 将then里面的数据放到微队列,等待状态完成后执行
this._pushHandlers(onFulfilled, FULFILLED, resolve, reject); //成功的
this._pushHandlers(onRejected, REJECTED, resolve, reject); //失败的
this._runHandlers(); //重新执行队列
});
}
//处理失败的场景
catch(onRejected) {
return this.then(null, onRejected);
}
//无论失败还是成功都会执行该函数
finally(onSettled) {
return this.then(
(data) => {
onSettled();
return data;
},
(reason) => {
onSettled();
return reason;
}
);
}
_changeState(newState, value) {
if (this._state != PENDING) {
//要是当前start不是挂起状态,说明已经执行了,那么就return,不在执行
return;
}
this._state = newState;
this._value = value;
this._runHandlers(); //重新执行
}
// 成功的方法
_resolve(data) {
//状态和值
this._changeState(FULFILLED, data);
}
//失败的方法
_reject(fail) {
this._changeState(REJECTED, fail);
}
/* 返回已完成的promise;特殊情况:
1.传递的data本身就是es6的promise对象
2.传递的data是promiseLike(promise A+规范),返回新的promise,状态和其保持一致
*/
//成功的 编写静态的
static resolve(data) {
if (data instanceof MyPromise) {
return data;
}
return new MyPromise((resolve, reject) => {
if (isPromise(data)) {
data.then(resolve, reject);
} else {
resolve(data);
}
});
}
//失败的 编写静态
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
/*
Promise迭代器,包含多个Promise
全部Promise成功,则返回Promise成功,数据为所有Promise成功的数据,并且顺序是按照传入的顺序排列
只要有一个Promise失败,则返回的Promise失败,原因是第一个失败的Promise的原因
*/
static all(proms) {
return new MyPromise((resolve, reject) => {
try {
const result = [];
let count = 0; //promise总数
let fulfilledCount = 0; //已完成的数量
for (const p of proms) {
let i = count;
count++;
MyPromise.resolve(p).then((data) => {
fulfilledCount++;
result[i] = data;
if (fulfilledCount === count) {
//当前最后一个Promise完成
resolve(result);
}
}, reject);
}
if (count === 0) {
resolve(result);
}
} catch (error) {
reject(error);
}
});
}
/*
等待所有promise有结果之后
该方法返回的promise完成
并且按照顺序将所有结果汇总
*/
static allSettled(proms){
const ps = [];
for(const p of proms){
ps.push(
MyPromise.resolve(p).then(
(value) =>({
status:FULFILLED,
value
}),
(reason)=>({
status:REJECTED,
reason
})
)
)
}
return MyPromise.all(ps)
}
//返回的Promise与第一个有结果的一致
static race(proms){
return new MyPromise((resolve,reject)=>{
for(const p of proms){
MyPromise.resolve(p).then(resolve,reject)
}
})
}
}
//两个参数,在class类里面使用该参数
const pro = new MyPromise((resolve, reject) => {
setTimeout(()=>{
reject(1);
},1)
});
//互操作 自己写的Promise 和官方写的promise可以互相操作
// pro
// .then((data)=>{
// console.log(data);//1
// return new Promise((resolve)=>{
// resolve(2)
// })
// })
// .then((data)=>{
// console.log(data);//2
// })
// const pro2 = pro.finally((d)=>{
// console.log('finally',d);
// throw 123
// })
// setTimeout(()=>console.log(pro2))
// MyPromise.all([pro]).then(
// (data) => {
// console.log("成功", data);
// },
// (reason) => {
// console.log("失败", reason);
// }
// );
// const pro1 = MyPromise.allSettled([
// pro,
// MyPromise.resolve(2),
// MyPromise.resolve(3),
// MyPromise.resolve(4),
// 5
// ])
// pro1.then((result)=>{
// console.log(result)
// })
const pro2 = new MyPromise((resolve, reject) => {
setTimeout(()=>{
resolve(1);
},10)
});
const pro1 = MyPromise.race([pro,pro2]);
pro1.then(
(data)=>{
console.log('成功',data)
},
(reason)=>{
console.log('失败',reason)
}
)