1)构造函数中立即执行函数
2)resolve和reject,Promise.resolve()这样的方法是存在于构造函数的方法,在es6中用static关键字
3)状态机
4)实现then(链式调用),then应该返回同自己类型的promise,并且是全新的对象
5)实现resolve的异步调用,用了asyncQueue一个队列,将then传入的回调函数推入队列,没有调用resolve之前一定为pending状态,此时调用then就返回自身,得以保存队列完整,调用resolve之后再for循环 同步阻塞调用执行,返回一个全新的promise进行迭代
(resolvePromise)
是Promise处理的一个标准
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
export default class MyPromsie<T> {
private state: string = '';
private val: string = '';
private reason: string = '';
// 实现异步调用队列
private asyncQueue: IPromiseCBS[] = [];
constructor(executor: <T = any>(resolve?: (value?: any) => void, reject?: (reason?: any) => void) => void) {
// 初始化状态机
this.state = PENDING;
try {
executor((val: any) => { this.resolve(val) }, (reason: any) => { this.reject(reason) });
} catch (reason) {
this.reject(reason);
}
}
// then function
public then(onFulfilled?: (val: any) => any, onRejected?: (reason: any) => any): MyPromsie<T> {
let promise: MyPromsie<T>;
// 异步情况 还未通过resolve改变pending状态
if (this.state === PENDING) {
// 箭头函数 阻止this 丢失
const ele = { onFulfilled, onRejected } as IPromiseCBS;
this.asyncQueue.push(ele);
return this;
}
promise = new MyPromsie((resolve, reject) => {
if (this.state === FULFILLED) {
// onFuifilled 的参数为 fulfilled 状态时的val值,并返回一个新的值作为新的promise resolve的入参
try {
const x = onFulfilled(this.val)
resolve(x);
} catch (reason) {
reject(reason);
}
}
if (this.state === REJECTED) {
try {
const x = onRejected(this.reason)
// todo resolvePromise()
resolve(x);
} catch (reason) {
reject(reason);
}
}
});
console.log(promise);
return promise;
}
public catch() {
}
public finally() {
}
private resolve(val: any) {
if (this.state === PENDING) {
this.state = FULFILLED;
// 保存调用resolve的值
this.val = val;
this.queueExecutor();
}
}
private reject(reason: any) {
if (this.state === PENDING) {
this.state = REJECTED;
// 保存调用reject的值
this.reason = reason;
this.queueExecutor();
}
}
private queueExecutor() {
// 如果resolve被异步调用 队列必不为空
if (this.asyncQueue.length > 0) {
let promise: MyPromsie<any> = this;
// for 循环为 同步 阻塞调用
for (let index = 0; index < this.asyncQueue.length; index++) {
const element = this.asyncQueue[index];
promise = promise.then(element.onFulfilled, element.onRejected);
}
}
}
// Promise.resolve()
static resolve(val: any) {
console.log(`static resolve val = ${val}`)
}
// Promise.reject()
static reject(reason: any) {
console.log(`static reject reason = ${reason}`)
}
}
interface IPromiseCBS {
onFulfilled?: (val: any) => any;
onRejected?: (reason: any) => any;
}
实现Promise.all .race resolve reject,最终为
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
export default class MyPromsie<T> {
private state: string = '';
private val: string = '';
private reason: string = '';
// 实现异步调用队列
private asyncQueue: IPromiseCBS[] = [];
constructor(executor: <T = any>(resolve?: (value?: any) => void, reject?: (reason?: any) => void) => void) {
// 初始化状态机
this.state = PENDING;
try {
executor((val: any) => { this.resolve(val) }, (reason: any) => { this.reject(reason) });
} catch (reason) {
this.reject(reason);
}
}
// then function
public then(onFulfilled?: (val: any) => any, onRejected?: (reason: any) => any): MyPromsie<T> {
let promise: MyPromsie<T>;
// 异步情况 还未通过resolve改变pending状态
if (this.state === PENDING) {
// 箭头函数 阻止this 丢失
const ele = { onFulfilled, onRejected } as IPromiseCBS;
this.asyncQueue.push(ele);
return this;
}
promise = new MyPromsie((resolve, reject) => {
if (this.state === FULFILLED) {
// onFuifilled 的参数为 fulfilled 状态时的val值,并返回一个新的值作为新的promise resolve的入参
try {
const x = onFulfilled(this.val)
resolve(x);
} catch (reason) {
reject(reason);
}
}
if (this.state === REJECTED) {
try {
const x = onRejected(this.reason)
// todo resolvePromise()
resolve(x);
} catch (reason) {
reject(reason);
}
}
});
// console.log(promise);
return promise;
}
// 实质为 onFuifilled 回调为空
public catch(onRejected?: (reason: any) => any) {
this.then(null,onRejected);
}
// finally 总是被执行的 无论成功还是 promise被拒绝 先执行.then中 成功或者失败的回调再调用finally的回调函数
public finally(cbs: Function) {
cbs();
}
private resolve(val: any) {
if (this.state === PENDING) {
this.state = FULFILLED;
// 保存调用resolve的值
this.val = val;
this.queueExecutor();
}
}
private reject(reason: any) {
if (this.state === PENDING) {
this.state = REJECTED;
// 保存调用reject的值
this.reason = reason;
this.queueExecutor();
}
}
private queueExecutor() {
// 如果resolve被异步调用 队列必不为空
if (this.asyncQueue.length > 0) {
let promise: MyPromsie<any> = this;
// 这么写 如果onFulfilled onRejected如果有异步函数 依然是有问题的啊 得不到顺序执行
for (let index = 0; index < this.asyncQueue.length; index++) {
const element = this.asyncQueue[index];
promise = promise.then(element.onFulfilled, element.onRejected);
}
}
}
// Promise.resolve()
static resolve(val?: any) {
console.log(`static resolve val = ${val}`)
return new MyPromsie((resolve, reject) => {
resolve(val);
});
}
// Promise.reject()
static reject(reason?: any) {
console.log(`static reject reason = ${reason}`)
return new MyPromsie((resolve, reject) => {
reject(reason);
});
}
// 输入promise数组 哪个promise 先执行完就返回哪个
static race(pArray: MyPromsie<any>[]) {
return new MyPromsie((resolve, reject) => {
for (let i = 0; i < pArray.length; i++) {
pArray[i].then(resolve, reject)
};
})
}
// all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
// 如果有其中一个被 reject 则返回第一个失败的promise
static all(pArray: MyPromsie<any>[]) {
const arr = Array(pArray.length);
let i: number = 0;
return new MyPromsie((resolve, reject) => {
for (let index = 0; index < pArray.length; index++) {
const promise = pArray[index];
promise.then(val => {
arr[index] = val;
if (++i == pArray.length) {
// 注意这里只能等异步调用返回结果之后才能resolve
resolve(val);
};
}, reason => {
console.log(reason)
reject(reason);
});
}
});
}
}
interface IPromiseCBS {
onFulfilled?: (val: any) => any;
onRejected?: (reason: any) => any;
}
网友评论