Promise的状态
状态的改变是不可逆的
enum PROMISE_STATE {
PENDING = 'Pending',
FULFILLED = 'Fulfilled',
REJECTED = 'Rejected'
}
构造函数
- new Promise 传入executor 执行器,executor 构造器两个函数分别对应resolve和reject
- value 用于记录resolve的值
- reason 用于记录reject的值
- status 表示promise的状态
onFulfilledCallback/onRejectedCallback记录收集的callbacks
class MyPromise {
value: any = null;
reason: any = null;
status: StatusType = PROMISE_STATE.PENDING;
promiseName:string;
onFulfilledCallback: any = [];
onRejectedCallback: any = [];
constructor(executor: (resolve: Fn, reject: Fn) => void) {
// executor 执行器 传入后会立即执行
this.promiseName = 'MyPromise'+ count++
console.log('constructor',this.promiseName)
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
console.log('捕获执行器中的异常代码');
this.reject(error)
}
}
}
resolve
resolve主要用来将状态从pending->fulfilled,同时执行回调
this.value = value;
if (this.status === PROMISE_STATE.PENDING) {
this.status = PROMISE_STATE.FULFILLED
while (this.onFulfilledCallback.length) {
this.onFulfilledCallback.shift()(this.value);
}
}
reject
reject主要用来将状态从pending->rejected,同时执行回调
reject(reason: any) {
this.value = reason;
if (this.status === PROMISE_STATE.PENDING) {
this.status = PROMISE_STATE.REJECTED
while (this.onRejectedCallback.length) {
this.onRejectedCallback.shift()(this.value);
}
}
}
then
主要有两个作用
- 返回promise对象用于链式调用
pending阶段收集函数(依赖),在状态改变的时候执行回调
then(onFulfilled: Fn, onRejected?: Fn) {
// console.log('promise then函数代码会立即执行,而函数则是在状态变化过后执行')
// 没传置空
if (returnType(onFulfilled) != '[object Function]') {
onFulfilled = (value) => value
}
if (returnType(onRejected) != '[object Function]') {
onRejected = (reason) => reason
}
let promise = new MyPromise((res, rej) => {
if (this.status === PROMISE_STATE.FULFILLED) {
// 使用微任务包裹onFulfilled的执行 这就是为什么then里面的函数是个微任务
queueMicrotask(() => {
// 捕获then执行时候的异常
try {
// 获取then一个函数的返回值 作为下一个promise的函数的res值
// console.log(onFulfilled, 'onFulfilled', this.value)
const result = onFulfilled(this.value);
resolvePromise(promise, result, res, rej)
} catch (error) {
rej(error);
}
})
} else if (this.status === PROMISE_STATE.REJECTED) {
queueMicrotask(() => {
try {
// 获取then一个函数的返回值 作为下一个promise的函数的res值
const result = onRejected!(this.value);
rejectPromise(promise, result, res, rej)
} catch (error) {
rej(error);
}
})
} else if (this.status === PROMISE_STATE.PENDING) {
this.onFulfilledCallback.push(() => {
// // ==== 新增 ====
queueMicrotask(() => {
try {
// 获取成功回调函数的执行结果
const x = onFulfilled(this.value);
resolvePromise(promise, x, res, rej)
} catch (error) {
rej(error)
}
})
});
this.onRejectedCallback.push(() => {
queueMicrotask(() => {
try {
const x = onRejected!(this.value);
rejectPromise(promise, x, res, rej)
} catch (error) {
rej(error)
}
})
});
}
})
return promise;
}
Demo1
new MyPromise((res,rej)=>{
setTimeout(() => {
res('1111')
console.log('promise1')
}, 1000);
}).then((res)=>{
console.log('promise2')
return 2222+res
}).then((res)=>{
console.log('promise3')
console.log(res)
})
分析:
promise1的状态改变之后执行收集的回调函数,得到回调函数执行结果再次resolve 从而改变了promise2的状态,promise2状态改变执行回调
Demo2
new MyPromise((res,rej)=>{
setTimeout(() => {
console.log('promise1')
res('1111')
}, 1000);
}).then((res)=>MyPromise.resolve('2222'))
.then((res)=>{console.log(3333)})
.then((err)=>{ console.log('4444')})
分析:
promise1的状态改变之后执行收集的回调函数,执行到MyPromise.resolve创建一个fulfilled状态promise5对象,得到回调返回结果发现一个promise对象,对promise对象进行then调用,此时创建promise6,执行完毕之后promise2状态改变,执行回调打印3333,然后resolve(undefined),从而promise3状态改变打印4444,接着继续resolve(undefined)用于后续的链式调用
static resolve
返回一个fuifulled状态的promise对象
static resolve(val: any) {
return new MyPromise((resolve, reject) => {
if (val instanceof MyPromise) {
val.then(resolve, reject)
} else {
resolve(val)
}
})
}
static reject
返回一个rejected状态的promise对象
static reject(reason: any) {
return new MyPromise((resolve, reject) => {
if (reason instanceof MyPromise) {
reason.then(resolve, reject)
} else {
reject(reason)
}
})
}
all
当所有的promise都执行完毕了 才执行resolve,其中一个失败了就reject,当然也可以对promiseList进行一层catch,可用于并行多个请求 同都成功了再执行后续的操作
static all(promiseList: any) {
return new MyPromise((resolve, reject) => {
if (!isAllPromise(promiseList)) {
console.log('传递进来的列表中存在不是promise对象的');
reject([])
}
const values: any = [];
// 所有的promise都成功了 resolve 一个失败就reject
promiseList.forEach((promise: any) => {
promise.then((res: any) => {
values.push(res)
if (values.length == promiseList.length) {
resolve(values)
}
}, (reason: any) => {
reject(reason)
})
});
})
race
race意为赛跑 即一个promise状态fulfilled了 就resolve 可以用于请求多个服务器的同一个资源,那个优先返回就使用哪个
static race(promiseList: any) {
return new MyPromise((resolve, reject) => {
if (!isAllPromise(promiseList)) {
console.log('传递进来的列表中存在不是promise对象的');
reject([])
}
// 哪一个promise先执行完就resolve
promiseList.forEach((promise: any) => {
promise.then((res: any) => {
resolve(res)
}, (reason: any) => {
reject(reason)
})
});
})
}
allsettled
即不管promise的状态如何 执行完毕就resolve
static allSettled(promiseList: any) {
return new MyPromise((resolve, reject) => {
if (!isAllPromise(promiseList)) {
console.log('传递进来的列表中存在不是promise对象的');
reject([])
}
const values: any = [];
promiseList.forEach((promise: any) => {
promise.then((res: any) => {
values.push({
value: res,
status: 'Fulfilled'
})
}, (reason: any) => {
values.push({
status: 'Rejected',
value: reason
})
}).finally(()=>{
if (values.length == promiseList.length) {
resolve(values)
}
})
});
})
}
any
一个promise成功了就resolve,全部失败了就reject
static any(promiseList: any) {
return new MyPromise((resolve, reject) => {
if (!isAllPromise(promiseList)) {
console.log('传递进来的列表中存在不是promise对象的');
reject([])
}
const values: any = [];
// 哪一个promise先执行完就resolve
promiseList.forEach((promise: any) => {
promise.then((res: any) => {
resolve(res)
}, (reason: any) => {
values.push({
status: 'Rejected',
value: reason
})
if (values.length === promiseList.length) {
reject(values)
}
})
});
})
}
finally
不管promise的状态如何, 都会执行finally方法指定的callback
finally(callBack: Fn) {
return this.then(
() => MyPromise.resolve(callBack()).then(value => value),
() => MyPromise.resolve(callBack()).then((reason) => { throw reason }),
);
}
catch
捕获promise reject的情况 实现其实就是变相的调用then,等价于多写了一个then 且传递了第二个参数
catch(onRejected: Fn) {
return this.then(() => { }, onRejected)
}