前言
如果想实现一个Promise 需要从以下几个方面考虑
- 符合 promise A+规范
- Promise类的设计
- 状态设计(pending/fulfilled/reject)
- 如何实现 resolve
- 如何实现 reject
- 如何实现 then
什么是Promise A+ 规范
- “promise” is an object or function with a
then
method whose behavior conforms to this specification. - “thenable” is an object or function that defines a
then
method. - “value” is any legal JavaScript value (including
undefined
, a thenable, or a promise). - “exception” is a value that is thrown using the
throw
statement. - “reason” is a value that indicates why a promise was rejected.
- A promise must be in one of three states: pending, fulfilled, or rejected.
promise类的设计
我们在使用 Promise的时候,都是通过 new 关键字调用, 所以借助 ES6 class 实现 Promise的声明
class DDFPromise {
constructor(executor) {
executor(executor);
}
实现Promise 三种状态
我们在使用Promise时,注意到,Promise有三种状态 fulfill/reject/pending
- new Promise(()=> {}) 此时的状态为pending
- new Promise(()=> {}).then() 此时的状态为fulfill
- new Promise(()=> {}).catch() 此时的状态为reject
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
constructor(executor) {
this.status = PENDING_STATUS;
executor(executor);
}
}
new DDFPromise(() => {
console.log("代码执行");
});
如何实现 resolve
实现resolve 需要关注两个点
- 状态
- 返回值
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
constructor(executor) {
this.status = PENDING_STATUS;
this.value = null;
const resolve = (value) => {
if (this.status === PENDING_STATUS) {
this.status = FULFILL_STATUS;
console.log("resolve被执行", value);
** **this.value = value
}
};
executor(resolve);
}
}
new DDFPromise((resolve) => resolve("resolve传入的参数"))
如何实现 reject
实现resolve 需要关注两个点
- 状态
- 返回值
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
constructor(executor) {
this.status = PENDING_STATUS;
this.value = null;
const resolve = (value) => {
if (this.status === PENDING_STATUS) {
this.status = FULFILL_STATUS;
console.log("resolve被执行", value);
this.value = value
}
};
const reject = (reason) => {
if (this.status === PENDING_STATUS) {
this.status = REJECT_STATUS;
this.reason = reason;
}
};
executor(resolve, reject);
}
}
new DDFPromise((resolve, reject) => {
resolve("resolve传入的参数");
reject("reject传入的参数");
})
如何实现 then
实现then 需要关注 以下几点
- then方法的两个入参
- then方法的两个入参 如何与constructor中定义的resolve/reject做关联
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
constructor(executor) {
this.status = PENDING_STATUS;
this.value = null;
this.reason = null;
const resolve = (value) => {
if (this.status === PENDING_STATUS) {
this.status = FULFILL_STATUS;
this.value = value;
this.onfulfilled(this.value);
}
};
const reject = (reason) => {
if (this.status === PENDING_STATUS) {
this.status = REJECT_STATUS;
this.reason = reason;
this.onrejected(this.reason);
}
};
executor(resolve, reject);
}
then(onfulfilled, onrejected) {
this.onfulfilled = onfulfilled;
this.onrejected = onrejected;
}
}
const ddfPro = new DDFPromise((resolve, reject) => {
resolve("resolve传入的参数");
// reject("reject传入的参数");
});
ddfPro.then(
(res) => {
console.log("fulfilled", res);
},
(err) => {
console.log("reject", err);
}
);
上边代码执行时报错 this.onfulfilled is not a function,报错的原因:new Prose(()=>{}) 入参的代码会立刻执行,而执行时this.onrejected,还没有声明,其实我们可以借助 Event Loop 解决此问题
解决then方法声明 调用时报错
queueMicrotask | setTimeout
const PENDING_STATUS = "pending";
const FULFILL_STATUS = "fulfill";
const REJECT_STATUS = "reject";
class DDFPromise {
constructor(executor) {
this.status = PENDING_STATUS;
this.value = null;
this.reason = null;
const resolve = (value) => {
if (this.status === PENDING_STATUS) {
this.status = FULFILL_STATUS;
queueMicrotask(() => {
this.value = value;
this.onfulfilled(this.value);
});
}
};
const reject = (reason) => {
if (this.status === PENDING_STATUS) {
this.status = REJECT_STATUS;
queueMicrotask(() => {
this.reason = reason;
this.onrejected(this.reason);
});
}
};
executor(resolve, reject);
}
then(onfulfilled, onrejected) {
this.onfulfilled = onfulfilled;
this.onrejected = onrejected;
}
}
const ddfPro = new DDFPromise((resolve, reject) => {
// resolve("resolve传入的参数");
// reject("reject传入的参数");
});
ddfPro.then(
(res) => {
console.log("fulfilled", res);
},
(err) => {
console.log("reject", err);
}
);
总结
经过如上步骤,只完成了Promise的基本操作,