Promise基本实现
包含Promise A+规范,then,catch,finally以及一些静态方法
/**
* Promise基本用法
* new Promise((resolve, reject) =>{})
*/
// 声明一些Promise状态的变量
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECT = 'rejected';
/**
* 将任务放入微队列辅助方法
* @param {Function} callback
*/
function runMicroTask(callback) {
// node 环境处理
if (process && process.nextTick) {
process.nextTick(callback);
} else if (MutationObserver) {
// 浏览器环境处理,创建一个观察器,观察元素变化,如果有变化则将callback放入微队列
const p = document.createElement('p');
const observer = new MutationObserver(callback);
observer.observe(p, {
childList: true,
});
p.innerHTML = '1';
} else {
// 其他情况
setTimeout(callback, 0);
}
}
/**
* 判断obj是否是一个promise
* @param {Object} obj
*/
function isPromise(obj) {
return !!(obj && typeof obj === 'object' && typeof obj.then === 'function');
}
class MyPromise {
// 声明一个构造器,接受一个参数为函数
constructor(executor) {
// promise 状态默认为pending
this._state = PENDING;
// promise 返回的数据默认为undefined
this._value = undefined;
// promise 已决后存放后续处理函数的队列
this._handlers = [];
// 执行函数,传递两个参数resolve和reject
try {
executor(this._resolve.bind(this), this._reject.bind(this));
} catch (error) {
this._reject(error);
}
}
/**
* 标记当前任务完成
* @param {any} data 完成任务后返回的数据
*/
_resolve(data) {
this._changeState(FULFILLED, data);
}
/**
* 标记当前任务失败
* @param {any} reason 任务失败后返回的原因
*/
_reject(reason) {
this._changeState(REJECT, reason);
}
/**
* 更改任务状态
* @param {string} state 状态
* @param {any} value 数据
*/
_changeState(state, value) {
// promise 状态不可逆
if (this._state !== PENDING) {
return;
}
this._state = state;
this._value = value;
// 状态变化后也应该执行一次任务队列
this._runHandlers();
}
/**
* 实现Promise A+ 规范的then
* @param {Function} onFulfilled Promise 成功后执行的函数
* @param {Function} onRejected Promise 失败后执行的函数
* @returns 返回一个Promise
*/
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 将后续处理函数放入队列
this._pushHandlers(onFulfilled, FULFILLED, resolve, reject);
this._pushHandlers(onRejected, REJECT, resolve, reject);
// 执行队列中的任务
this._runHandlers();
});
}
/**
* 进处理失败的场景
* @param {Function} onRejected
* @returns
*/
catch(onRejected) {
return this.then(null, onRejected);
}
/**
* 无论成功或失败都会运行
* @param {Function} onSettled
*/
finally(onSettled) {
return this.then(
(data) => {
onSettled();
return data;
},
(reason) => {
onSettled();
throw reason;
}
);
}
/**
* 向队列中添加处理函数
* @param {Function} executor
* @param {String} state
* @param {Function} resole
* @param {Function} reject
*/
_pushHandlers(executor, state, resolve, reject) {
this._handlers.push({ executor, state, resolve, reject });
}
/**
* 根据实际情况执行任务中的队列
*/
_runHandlers() {
// 如果当前Promise 的状态为pending 则不执行
if (this._state === PENDING) {
return;
}
// 否则遍历处理队列中的任务,处理之后将任务删掉避免重复执行
while (this._handlers[0]) {
this._runOneHandler(this._handlers[0]);
this._handlers.shift();
}
}
/**
* 执行任务
* @param {Object} param0 解构任务
*/
_runOneHandler({ executor, state, resolve, reject }) {
// 将任务放入微队列
runMicroTask(() => {
// 如果当前Promise 的状态和该任务的状态不一致则不执行
if (this._state !== state) {
return;
}
// 如果then中没有传递成功/失败后的处理函数,则和当前Promise 状态保持一致
if (typeof executor !== 'function') {
this._state === FULFILLED ? resolve(this._value) : reject(this._value);
return;
}
// 正常执行的情况
try {
const result = executor(this._value);
if (isPromise(result)) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
});
}
/**
* resolve静态方法实现
* 1.如果data是一个promise
* 2.如果data是一个promiselike,返回一个新的promise,状态和它保持一致
* @param {*} data
*/
static resolve(data) {
if (data instanceof MyPromise) {
return data;
}
return new MyPromise((resolve, reject) => {
if (isPromise(data)) {
data.then(resolve, reject);
} else {
resolve(data);
}
});
}
/**
* reject静态方法实现
* 1.直接返回一个promise,状态为reject
* @param {*} reason
*/
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
}
//测试...
new MyPromise((resolve, reject) => {
console.log('myPromise excute');
resolve(1);
}).then(
(r) => {},
(r) => {}
);