API的特性与手写源码
构造函数
- promise有状态pending、rejected和resolved,所以应该有个变量来保存状态
- 构造函数参数excutor是个同步执行的回调函数,函数执行的参数是两个函数resolved和rejected,所以promise内部需要定义两个函数,并且在构造行数中执行excutor的地方传入
- .then中会传入回调函数onResolved和onRejected,在resolved和rejected内会分别会触发对应的回调函数,所以需要两个数组保存then中传进来的回调
- resolved和rejected只能执行一次,执行后promise的状态会改变,且参数会传递给回调函数
- onRejected和onResolved异步执行
- excutor执行抛异常会直接执行rejected,所以excutor的执行需要catch错误
const PENDING = "PENDING";
const RESOLVED = "resolved";
const REJECTED = "rejected";
function MyPromise(excutor){
// promise内部保存着状态值
this.status = PENDING;
this.data = null;
// then方法传进来的回调函数此保存
this.onResolvedList = [];
this.onRejectedList = [];
let resolved = (value) => {
// resolved函数只能执行一次,所以先判断状态是不是pending
if(this.status !== PENDING){
return;
}
// 变更状态为resolved
this.status = RESOLVED;
// 数据为传进来的值
this.data = value;
// 判断是否已经有onResolved回调已经穿入,有则异步执行
if(this.onResolvedList.length > 0){
setTimeout(() => {
this.onResolvedList.forEach(onResolved => {
onResolved(value);
});
}, 0);
}
}
let rejected = (reason) => {
if(this.status !== PENDING){
return
}
this.status = REJECTED;
this.data = reason;
if(this.onRejectedList.length > 0){
setTimeout(() => {
this.onRejectedList.forEach(onRejected => {
onRejected(reason);
});
});
}
}
try{
// 执行器函数同步执行,且参数为promise内定义的resolve和rejected
excutor(resolved, r