Promise
ES6 增加的异步编程方式,避免了回调地狱,一个 promise 有三个状态 pending,fulfilled,rejected,初始化后为 pending 状态,在构造函数中会传入 resolve,reject 两个函数,调用 resolve 后改变状态为 fulfilled,调用 rejected 后改变状态为 rejected,一旦状态从 pending 进行转遍后不会再次转遍。调用 then 函数,返回新的 promise,以此从无限回调转换为链式调用,then 过多时又会陷入链式地狱。
核心代码
import { DEFAULT_OP, catchError, throwValue } from '@/shared';
import { resolvePromise } from './resolvePromise';
import {
ASYNC,
PromiseState,
BestPromiseFulfilledResult,
BestPromiseRejectedResult,
} from './utils';
export class BestPromise<T> {
/** 状态值 */
private state: PromiseState = PromiseState.PENDING;
/** 成功回调 */
private onFulfilled: (() => void)[] = [];
/** 失败回调 */
private onRejected: (() => void)[] = [];
/** 结束回调 */
private onFinally: (() => void)[] = [];
private value!: T;
private reason!: any;
constructor(fn: (resolve: (value: T) => void, reject: (reason: any) => void) => void) {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
catchError(() => fn(this.resolve, this.reject), this.reject);
}
/**
* 返回成功状态
* @param val 成功值
*/
static resolve<V>(val: V) {
return new BestPromise<V>(resolve => {
resolve(val);
});
}
/**
* 返回失败状态
* @param val 失败值
*/
static reject(val: any) {
return new BestPromise<any>((_, reject) => {
reject(val);
});
}
/**
* 任意一个promise状态变更,返回的promise就会状态变更
* @param promises promise列表
*/
static race(promises: BestPromise<any>[]) {
return new BestPromise((resolve, reject) => {
for (const promise of promises) {
promise.then(
value => resolve(value),
reason => reject(reason)
);
}
});
}
/**
* 任意一个promise状态变更为fulfilled ,返回resolve,
* 所有promise状态变更为rejected,返回reject列表
* @param promises promise列表
*/
static any(promises: BestPromise<any>[]) {
const len = promises.length;
let count = 0;
const reasonList: any[] = [];
return new BestPromise((resolve, reject) => {
const onReject = (reason: any, index: number) => {
reasonList[index] = reason;
if (++count === len) reject(reasonList);
};
for (let i = 0; i < len; i++) {
const promise = promises[i];
promise.then(
value => resolve(value),
reason => onReject(reason, i)
);
}
});
}
/**
* 任意一个promise状态变更为rejected,返回reject
* 所有promise状态变更为fulfilled,返回resolve列表
* @param promises promise列表
*/
static all(promises: BestPromise<any>[]) {
const len = promises.length;
let count = 0;
const value: any[] = [];
return new BestPromise((resolve, reject) => {
const onResolve = (reason: any, index: number) => {
value[index] = reason;
if (++count === len) resolve(value);
};
for (let i = 0; i < len; i++) {
const promise = promises[i];
promise.then(
value => onResolve(value, i),
reason => reject(reason)
);
}
});
}
/**
* 所有promise状态都变更时返回
* @param promises promise列表
*/
static allSettled(
promises: BestPromise<any>[]
): BestPromise<(BestPromiseFulfilledResult<any> | BestPromiseRejectedResult)[]> {
const len = promises.length;
let count = 0;
const statusList: (BestPromiseFulfilledResult<any> | BestPromiseRejectedResult)[] = [];
return new BestPromise(resolve => {
const on = (
status: BestPromiseFulfilledResult<any> | BestPromiseRejectedResult,
index: number
) => {
statusList[index] = status;
if (++count === len) resolve(statusList);
};
for (let i = 0; i < len; i++) {
const promise = promises[i];
promise.then(
value => on({ status: 'fulfilled', value }, i),
reason => on({ status: 'rejected', reason }, i)
);
}
});
}
/**
* 成功函数
* @param value 成功值
*/
private resolve(value: T): void {
if (this.state === PromiseState.PENDING) {
this.state = PromiseState.FULFILLED;
this.value = value;
this.onFulfilled.forEach(fn => fn());
this.onFinally.forEach(fn => fn());
}
}
/**
* 失败函数
* @param reason 失败值
*/
private reject(reason: any): void {
if (this.state === PromiseState.PENDING) {
this.state = PromiseState.REJECTED;
this.reason = reason;
this.onRejected.forEach(fn => fn());
this.onFinally.forEach(fn => fn());
}
}
/**
* 链式调用函数,返回新的promise
* @param onFulfilled 成功时触发
* @param onRejected 失败时触发
*/
then<V>(
onFulfilled: (value: T) => V | BestPromise<V>,
onRejected: (reason: any) => any = throwValue
): BestPromise<V> {
const promise = new BestPromise<V>((resolve, reject) => {
// 统一触发函数
const onFn = (val?: V | BestPromise<V>) =>
val !== undefined && ASYNC(() => resolvePromise<V>(promise, val, resolve, reject));
const onFulfill = () => onFn(catchError(() => onFulfilled(this.value), reject));
const onReject = () => onFn(catchError(() => onRejected(this.reason), reject));
if (this.state === PromiseState.FULFILLED) {
// 如果当前状态已为fulfill则直接触发
onFulfill();
} else if (this.state === PromiseState.REJECTED) {
// 如果当前状态已为reject则直接触发
onReject();
} else {
// 如果当前状态还未确定则暂存函数
this.onFulfilled.push(onFulfill);
this.onRejected.push(onReject);
}
});
return promise;
}
/**
* 捕获错误,可捕获error错误或者reject
* @param onReject 任意函数
*/
catch(onReject: (reason: any) => any) {
return this.then(DEFAULT_OP, onReject);
}
/**
* 在promise执行完毕后执行
* @param fn 任意函数
*/
finally(fn: () => void): void {
this.state === PromiseState.PENDING ? this.onFinally.push(fn) : fn();
}
}