const PENDING = 'PENDING',
FULFILLED = 'FULFILLED',
REJECTED = 'REJECTED';
function resolvePromise(promise2,x,resolve,reject){
// 如果promise2和x引用的是同一个对象,以typeError为理由拒绝
if(promise2===x){
reject(new TypeError('类型错误!'));
}
//是否调用过
let called= false;
if(typeof x==='object' && x!==null||typeof x === 'function'){
try {
let then=x.then
if(typeof then==='function'){
then.call(x,(y)=>{
if(called) return
called=true;
//产生新的promise重新走一遍
resolvePromise(promise2,y,resolve,reject)
},r=>{
if(called) return
called=true;
reject(r)
})
}else{
resolve(x)
}
} catch (error) {
//如果在取then的时候报错 直接返回错误
if(called) return
called=true;
reject(error)
}
}else{
//如果x为普通值 直接返回
resolve(x)
}
}
class MyPromise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulFilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED
this.value = value
}
this.onFulFilledCallbacks.forEach(fn => fn())
//收集异步 发布
}
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED
this.reason = reason
}
this.onRejectedCallbacks.forEach(fn => fn())
//收集异步 发布
}
try {
executor(resolve, reject);
} catch (error) {
reject(error)
}
}
then(onFulFilled, onRejected) {
// onFulFilled与onRejected为可选值
onFulFilled = typeof onFulFilled ==='function' ? onFulFilled :value=>value
onRejected = typeof onRejected ==='function' ? onRejected :reason=>{
throw reason
}
let promise2 = new MyPromise((resolve,reject)=>{
//x的值可能为 JavaScript普通值
//也可能为一个promise对象 需要一个函数单独处理这个部分
if (this.status === FULFILLED) {
//此时传入promise2时 这个promise2还没有初始化完 可以利用settimeout解决
setTimeout(() => {
// 需要捕获错误
try {
let x = onFulFilled(this.value)
resolvePromise(promise2,x,resolve,reject)
} catch (error) {
reject(error)
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
} catch (error) {
reject(error)
}
}, 0);
}
if (this.status == PENDING) {
//当then后status为PENDING 需要收集异步处理 等待resolve和reject触发
this.onFulFilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulFilled(this.value)
resolvePromise(promise2,x,resolve,reject)
} catch (error) {
reject(error)
}
}, 0);
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2,x,resolve,reject)
} catch (error) {
reject(error)
}
}, 0);
})
}
});
return promise2;
}
catch(errorCallback){
return this.then(null,errorCallback)
}
}
module.exports = MyPromise
手写Promise函数源码完整版
最新推荐文章于 2023-02-01 16:11:15 发布