前面已经把所有的函数放到对列里了,里面有些函数会执行,有些不会执行,这得取决于状态。接下来去遍历这个对列,把函数拿出来,看看怎么处理。
/**
* @description: 根据实际情况 执行队列里
* @return {*}
*/
_runHandler() {
if (this._state === PENDING) {
// 任务仍在挂起
return;
}
}
那状态改变了,需要看队列里的情况,所以状态一改变,就要执行队列。
_changeState(state, value) {
if (this._state !== PENDING) return;
this._state = state;
this._value = value;
this._runHandler(); //状态改变 执行队列里的任务
}
调用then的时候,向队列添加了函数,那这时也要看一下队列里函数的状态。
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {
this._pushHandler(onFulfilled, FULFILLED, resolve, reject);
this._pushHandler(onRejected, REJECTED, resolve, reject);
this._runHandler(); //执行队列
});
}
ok,这时候,可以去处理队列了,当状态不是pending的时候,要执行相应的函数。
/**
* @description: 根据实际情况 执行队列里
* @return {*}
*/
_runHandler() {
if (this._state === PENDING) {
// 任务仍在挂起
return;
}
for (const handler of this._handlers) {
this._runOneHandler(handler);
}
}
/**
* @description: 处理队列里的每一个 对象
* @param {Object} handler 队列里的对象
* @return {*}
*/
_runOneHandler(handler) {}
对了,处理完一个函数,要把它从队列里移除掉,不然如果后面再次调用then,那队列里的函数就会一直累加。
_runHandler() {
if (this._state === PENDING) {
// 任务仍在挂起
return;
}
for (const handler of this._handlers) {
this._runOneHandler(handler);
this._handlers.shift();//移除执行完的函数
}
}
嘿嘿,是不是就觉得访问了就删除,到最后就可以完全删除?nonono,不信你试试。
应该是while循环,才能搞定。
_runHandler() {
if (this._state === PENDING) {
// 任务仍在挂起
return;
}
while (this._handlers[0]) {
const handler = this._handlers[0];
this._runOneHandler(handler);
this._handlers.shift(); //移除执行完的函数
}
}
ok,万事俱备,只欠东风。现在就来处理下这个runOneHandler执行器。
/**
* @description: 处理队列里的每一个 对象
* @param {Object} handler 队列里的对象
* @return {*}
*/
_runOneHandler(handler) {}
现在把这个处理过程放到微队列里去执行。这个参数handler包含了then方法传递的函数和函数需要运行的状态,只有当myPromise的当前状态与队列里函数状态一致,才会执行该函数。
_runOneHandler(handler) {
runMicroTask(() => {
if (this._state !== handler.state) {
//状态不匹配
return;
};
});
}
还有一种情况,then没有传第二个参数,或者第二个参数不是一个函数。那这种要怎么处理?看下Promise的一个情况:
const p1 = p.then(function A1() {}) //第二个参数未传 则p1 的状态 和 p 的状态一致。
_runOneHandler(handler) {
runMicroTask(() => {
if (this._state !== handler.state) {
//状态不匹配
return;
}
//第二个参数不是函数 则返回的promise状态和当前的状态一致
if (typeof handler.excutor !== "function") {
this._state === FULFILLED
? handler.resolve(this._value)
: handler.reject(this._value);
return;
}
});
}
来看一下效果,我让myPromise1秒后失败,不传失败的处理函数,然后来看看当前myPromise和then返回的myPromise。
const p = new myPromise((resolve, reject) => {
setTimeout(() => {
reject(1213);
}, 1000);
});
const p1 = p.then(function A1() {});
setTimeout(() => {
console.log("p", p);
console.log("p1", p1);
}, 2000);
再来看看成功的情况。1秒后成功,不传成功的处理函数。
const p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
});
const p1 = p.then();
setTimeout(() => {
console.log("p", p);
console.log("p1", p1);
}, 2000);
现在两种特殊状态都处理了,那现在就来处理正常的结果。如果then传入的函数成功执行,那就执行resolve,如果出现错误了,那就执行reject。
_runOneHandler({ excutor, state, resolve, reject }) {
runMicroTask(() => {
if (this._state !== state) {
//状态不匹配
return;
}
if (typeof excutor !== "function") {
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
// 根据`then`里面函数执行状态来 执行
try {
excutor(this._value);
} catch (error) {
reject(error);
}
});
}
现在来看看then返回的myPromise状态。myPromise成功,执行then里的第一个函数(成功),执行期间抛出错误。
const p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(1);
});
});
const p1 = p.then((value) => {
throw "错误!"; //运行期间抛出错误
return 1234;
});
setTimeout(() => {
console.log("p1", p1);
}, 100);
ok,被拒绝了,值为抛出的错误。
现在来处理then第一个函数运行没问题时的情况。
_runOneHandler({ excutor, state, resolve, reject }) {
runMicroTask(() => {
if (this._state !== state) {
//状态不匹配
return;
}
if (typeof excutor !== "function") {
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
try {
const res = excutor(this._value);
resolve(res); //保存成功的值
} catch (error) {
reject(error);
}
});
}
...
const p1 = p.then((value) => {
return 1234;
});
ok了,能使用了。优化点小细节,如果then的参数返回的是一个myPromise,那怎么处理。
const p1 = p.then((value) => {
return new myPromise((resolve, reject)=>{});
});
这种情况下,被圈住的这两个的状态和数据是一样的。那在
_runOneHandler函数里又得处理一下这种情况。那怎么去判断是不是一个promise呢?其实不用符合ES6的,只要是满足了promise A+,那就是一个promise。
/**
* @description: 判断参数是不是一个 promise 对象 只要满足 Promise A+ 就是promise
* @param {any} obj
* @return {Boolean}
*/
function isPromise(obj) {
return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}
_runOneHandler({ excutor, state, resolve, reject }) {
runMicroTask(() => {
if (this._state !== state) {
//状态不匹配
return;
}
if (typeof excutor !== "function") {
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
try {
const res = excutor(this._value);
if (isPromise(res)) {
res.then(resolve, reject);
} else {
resolve(res);
}
} catch (error) {
reject(error);
}
});
}
到这里呢,就完成了整个Promise A+规范了,还是很曲折的,这就当做是笔记了,里面一堆的基础知识点和高阶函数,还要了解Promise的功能才能下手,着实有点难。下面是整个myPromise。
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
/**
* @description: 判断参数是不是一个 promise 对象 只要满足 Promise A+ 就是promise
* @param {any} obj
* @return {Boolean}
*/
function isPromise(obj) {
return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}
/**
* @description: 运行一个微队列任务 or 把传递的函数放到微队列里
* @param {Function} callback 函数
* @return {*}
*/
function runMicroTask(callback) {
// node environments
// if (process && process.nextTick) {
// console.log("34", 34);
// process.nextTick(callback);
// } else
if (MutationObserver) {
const a = document.createElement("span");
new MutationObserver(callback).observe(a, {
childList: true,
});
a.innerHTML = 1;
} else {
setTimeout(callback, 0);
}
}
class myPromise {
/**
* @description: 构造函数
* @param {Function} excutor 执行器,描述任务的执行过程 立即执行
* @return {*}
*/
constructor(excutor) {
this._state = PENDING; //状态
this._value = undefined; //数据
this._handlers = []; //处理函数形成的队列
try {
excutor(this._resolve.bind(this), this._reject.bind(this)); //绑定this
} catch (error) {
this._reject(error);
}
}
/**
* @description: 向处理队列中添加一个函数,并标记类型
* @param {Function} excutor 需要存入的函数
* @param {String} state 该函数什么状态下执行
* @param {Function} resolve 让then函数返回的 promise 成功
* @param {Function} reject 让then函数返回的 promise 失败
* @return {*}
*/
_pushHandler(excutor, state, resolve, reject) {
this._handlers.push({
excutor,
state,
resolve,
reject,
});
}
/**
* @description: 根据实际情况 执行队列里
* @return {*}
*/
_runHandler() {
if (this._state === PENDING) {
// 任务仍在挂起
return;
}
while (this._handlers[0]) {
const handler = this._handlers[0];
this._runOneHandler(handler);
this._handlers.shift(); //移除执行完的函数
}
}
/**
* @description: 处理队列里的每一个 对象
* @param {Object} handler 队列里的对象
* @return {*}
*/
_runOneHandler({ excutor, state, resolve, reject }) {
runMicroTask(() => {
if (this._state !== state) {
//状态不匹配
return;
}
if (typeof excutor !== "function") {
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
try {
const res = excutor(this._value);
if (isPromise(res)) {
res.then(resolve, reject);
} else {
resolve(res);
}
} catch (error) {
reject(error);
}
});
}
/**
* @description: then 成功或失败要做的事 满足 Promise A+ 规范
* @param {Function} onFulfilled 成功的回调
* @param {Function} onRejected 失败的回调
* @return {Object} Object 返回一个新的Promise
*/
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {
this._pushHandler(onFulfilled, FULFILLED, resolve, reject);
this._pushHandler(onRejected, REJECTED, resolve, reject);
this._runHandler(); //执行队列
});
}
/**
* @description: 改变状态和数据
* @param {String} state 状态
* @param {any} value 数据
* @return {*}
*/
_changeState(state, value) {
if (this._state !== PENDING) return;
this._state = state;
this._value = value;
this._runHandler(); //状态改变 执行队列里的任务
}
/**
* @description: 标记当前任务完成
* @param {any} value 任务完成的相关数据
*/
_resolve(value) {
//改变状态和数据
this._changeState(FULFILLED, value);
}
/**
* @description: 标记当前任务失败
* @param {any} reason 任务失败的相关数据
*/
_reject(reason) {
//改变状态和数据
this._changeState(REJECTED, reason);
}
}
export default myPromise;