promise实现
-
定义类,声明状态和值,声明一个执行者executor,resolve或rejected方法在executor中调用
-
then方法的实现(包含then接受的两个函数,以及pending的实现)
-
链式的实现
-
返回类型(promise or 普通值)
-
Promise.resolve/race/all/reject实现
class PR {
static PENDING = 'pending';
static FULFILLED = 'fulfilled';
static REJECTED = 'rejected';
constructor(executor) {
this.status = PR.PENDING; // 初始化状态为pending
this.value = null; // 值
// 4. 处理promise为pending时的状态
this.callbacks = [];
try {
// executor执行者
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (e) {
this.reject(e)
}
}
// Promise.resolve实现
static resolve(value) {
return new PR((resolve, reject) => {
if (value instanceof PR) {
value.then(resolve, reject);
} else {
resolve(value);
}
});
}
// Promise.reject实现
static reject(reason) {
return new PR((_, reject) => {
reject(reason);
});
}
// Promise.race实现
static race(promises) {
return new PR((resolve, reject) => {
promises.map(promise => {
promise.then(value => {
resolve(value);
});
});
});
}
// Promise.all实现
static all(promises) {
let resolves = [];
return new PR((resolve, reject) => {
promises.forEach((promise, index) => {
promise.then(
value => {
resolves.push(value);
if (resolves.length == promises.length) {
resolve(resolves);
}
},
e => {
reject(e);
}
);
});
});
}
resolve(value) {
if (this.status === PR.PENDING) {
this.status = PR.FULFILLED; // 状态置为完成
this.value = value;
// 4.2 resovle中添加处理callback方法并且定义为异步任务
setTimeout(() => {
this.callbacks.map(callback => {
callback.onFulfilled(value)
})
})
}
}
reject(value) {
if (this.status === PR.PENDING) {
this.status = PR.REJECTED; // 状态置为失败
this.value = value;
// 4.3 reject中添加处理callback方法并定义为异步任务
setTimeout(() => {
this.callbacks.map(callback => {
callback.onRejected(value)
})
})
}
}
// 2. then方法来处理状态的改变
then(onFulfilled, onRejected) { // then接收两个参数,即成功和失败的回调函数
// 因为两个函数参数不是必填的,所以需要多做一步操作,设置默认值为函数
if (typeof onFulfilled != 'function') {
onFulfilled = value => value;
}
if (typeof onRejected != 'function') {
onRejected = value => value
}
// 5. 链式调用
let promise = new PR((resolve, reject) => {
// 4.1 pending的处理
if(this.status == PR.PENDING) {
let obj = {
onFulfilled: value => {
try {
let result = onFulfilled(value)
// 6. 返回类型,实现不同类型不同处理机制
this.parse(promise, result, resolve, reject);
} catch (e) {
onRejected(e)
}
},
onRejected: value => {
try {
let result = onRejected(value)
this.parse(promise, result, resolve, reject);
} catch (e) {
onRejected(e)
}
}
}
this.callbacks.push(obj)
}
// 成功
if (this.status == PR.FULFILLED) {
// 3. 使用setTimeout来将onFulfilled与onRejected做为异步宏任务执行
setTimeout(() => {
try {
let result = onFulfilled(this.value)
this.parse(promise,result, resolve, reject);
} catch (e) {
onRejected(e);
}
});
}
// 失败
if (this.status == PR.REJECTED) {
setTimeout(() => {
try {
let result = onRejected(this.value)
this.parse(promise, result, resolve, reject);
} catch (e) {
onRejected(e);
}
});
}
})
return promise;
}
// 代码复用
parse(promise, result, resolve, reject) {
if (promise == result) {
throw new TypeError("Chaining cycle detected for promise");
}
try {
if(result instanceof PR) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (e) {
reject(e);
}
}
}
// 举例
PR.resolve("resolve").then(value => {
console.log(value);
});
let p = new PR((resolve, reject) => {
resolve(1)
}).then(value => {
console.log(value);
return new PR((resolve, reject) => {
resolve('返回promise')
})
}).then(value => {
console.log(value)
})
备注: 参考自后盾人大叔(绝绝子)