Skip to main content

手写 Promise

Promise 内部实现

MyPromise.ts
export enum PromiseState {
pending = "pending",
fulfilled = "fulfilled",
rejected = "rejected",
}

type PromiseOnFulfilled<T extends unknown> = (value: T) => void;

type PromiseOnRejected = (reason: any) => void;

type PromiseHandler<T> = {
state: keyof typeof PromiseState;
executor?: PromiseOnFulfilled<T> | PromiseOnRejected;
resolve: PromiseOnFulfilled<T>;
reject: PromiseOnRejected;
};

/**
* 把一个函数放到微队列里面去
*/
const runMicroTask = (callback: () => void) => {
const p = document.createElement("p");
const observer = new MutationObserver(() => {
callback();
});
observer.observe(p, {
childList: true,
});
p.innerHTML = "1";
};

const isPromise = (obj: any) => {
return !!(obj && typeof obj === "object" && typeof obj.then === "function");
};

class MyPromise<T extends unknown> {
/**
* 内部状态
*/
private state: keyof typeof PromiseState = PromiseState.pending;

private value: T | undefined = undefined;

/**
* 存放then函数里面onFulfilled 和 onRejected 的回调函数
* 通过 state 来区分 存放的是 注册的回调函数 还是失败的回调函数
*/
private handlers: PromiseHandler<T>[] = [];

/**
* 创建一个Promise
* @param executor {Function}
*/
constructor(
executor: (
resolve: PromiseOnFulfilled<T>,
reject: PromiseOnRejected
) => void
) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}

private resolve = (value?: T) => {
this.changeState(PromiseState.fulfilled, value);
};

private reject = (reason: any) => {
this.changeState(PromiseState.rejected, reason);
};

/**
* 更改 任务的状态
* @param state
* @param value
* @returns
*/
private changeState = (state: PromiseState, value: T | undefined) => {
if (this.state !== PromiseState.pending) {
return;
}
this.state = state;
this.value = value;
//状态变化执行队列
this.runHandlers();
};

/**
* 把 onFulfilled 和 onRejected 添加到任务队列里面去
* @param executor
* @param state
*/
private pushHandlers = (
executor: PromiseHandler<T>["executor"],
state: PromiseHandler<T>["state"],
resolve: PromiseHandler<T>["resolve"],
reject: PromiseHandler<T>["reject"]
) => {
this.handlers.push({
state,
executor,
resolve,
reject,
});
};

/**
* 执行注册到数组队列里面的函数
*/
private runHandlers = () => {
if (this.state === PromiseState.pending) {
return;
}
while (this.handlers[0]) {
this.runHandler(this.handlers[0]);
this.handlers.shift();
}
};

private runHandler = (handle: PromiseHandler<T>) => {
runMicroTask(() => {
if (handle.state !== this.state) {
return;
}
if (typeof handle.executor !== "function") {
this.state === PromiseState.fulfilled
? handle.resolve(this.value as T)
: handle.reject(this.value);
return;
}
try {
const result = handle.executor(this.value as T);
if (isPromise(result)) {
result.then(handle.resolve, handle.reject);
} else {
handle.resolve(result as T);
}
} catch (error) {
handle.reject(error);
}
});
};

/**
* then 注册的 onFulfilled 和 onRejected 的回调函数不会立即执行 会放到微队列里面去
* @param onFulfilled
* @param onRejected
* @returns MyPromise
*/
then = (
onFulfilled?: PromiseOnFulfilled<T>,
onRejected?: PromiseOnRejected
) => {
return new MyPromise((resolve, reject) => {
this.pushHandlers(onFulfilled, PromiseState.fulfilled, resolve, reject);
this.pushHandlers(onRejected, PromiseState.rejected, resolve, reject);
this.runHandlers();
});
};

/**
/**
* then函数 捕获异常错误的简写
* @param onRejected
* @returns MyPromise
*/
catch = (onRejected: PromiseOnRejected) => {
return this.then(undefined, onRejected);
};

/**
* 当任务状态不是pending的时候 就会调用这个函数
* @param onSettled
* @returns MyPromise
*/
finally = (onSettled: () => void) => {
return this.then(
(data) => {
onSettled();
return data;
},
(reason) => {
onSettled();
return reason;
}
);
};
}

export default MyPromise;

实现 Promise.resolve 静态方法

/**
* 1、传入的data可能是ES6的Promise
* 2、传入的data也可能是PromiseLike (Promise A+)的Promise 状态和其保持一致即可
*/
Promise.resolve = function (data) {
if (data instanceof Promise) {
return data;
}
return new Promise((resolve, reject) => {
if (isPromise(data)) {
data.then(resolve, reject);
} else {
resolve(data);
}
});
};

实现 Promise.reject 静态方法

Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason);
});
};

实现 Promise.all 静态方法

Promise.all = function (task) {
return new Promise((resolve, reject) => {
try {
let count = 0;
let fulfilledCount = 0;
let result = [];

for (const iterator of task) {
let i = count;
count++;
Promise.resolve(iterator).then((data) => {
fulfilledCount++;
result[i] = data;
if (fulfilledCount === count) {
resolve(result);
}
}, reject);
}

if (count === 0) {
resolve(result);
}
} catch (error) {
reject(error);
}
});
};

实现 Promise.allSettled 静态方法

Promise.allSettled = function (task) {
const promiseHandlers = [];
for (const iterator of task) {
promiseHandlers.push(
iterator.then(
(data) => {
return {
value: data,
status: "fulfilled",
};
},
(reason) => {
return {
reason: reason,
status: "rejected",
};
}
)
);
}
return Promise.all(promiseHandlers);
};

实现 Promise.race 静态方法

Promise.race = function (task) {
return new Promise((resolve, reject) => {
for (const iterator of task) {
Promise.resolve(iterator).then(resolve, reject);
}
});
};