class Promise{
constructor(executor){
//初始化状态、初始化成功时的值和失败时的原因
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
//解决resolve异步调用时,值无法被then获取
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
//定义resolve方法,将状态改为fulfilled并将参数设为成功的值,并且遍历执行成功的回调
//为了防止value或者reason再次被改变,这里只能在pending状态下才能执行
let resolve = value => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onResolvedCallbacks.forEach(fn=>fn());
}
};
//定义reject方法,将状态改为rejected并将参数设置为reason,并且遍历执行失败的回调
let reject = reason => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn=>fn());
}
};
//Promise实例当状态改变为rejected状态或者操作失败抛出异常错误,就会被catch方法捕获。
//所以在Promise实例中reject方法等同于抛出错误。如果Promise的状态已经变成了resolved,再抛出错误
try{
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled,onRejected) {
// onFulfilled如果不是函数,就忽略onFulfilled,直接返回value
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
// onRejected如果不是函数,就忽略onRejected,直接扔出错误
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
//返回一个新的promise对象实现链式调用
let promise2 = new Promise((resolve, reject) => {
if (this.state === 'fulfilled') {
// 异步
setTimeout(() => {
try {
//resovelePromise处理
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
if (this.state === 'rejected') {
// 异步
setTimeout(() => {
// 如果报错
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
if (this.state === 'pending') {
//对于异步执行的resolve和reject,在then中status没有改变,仍然为pending
//此时需要先把回调存下来,等之后resolve或reject开始执行时遍历调用
this.onResolvedCallbacks.push(() => {
// promise/A+规定onFulfilled或onRejected不能同步被调用,必须异步调用。我们就用setTimeout解决异步问题
setTimeout(() => {
try {
//因为我们可能在onFulfilled中返回一个promise,需要处理自己返回的promise和promise2的关系,避免循环引用
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
});
};
});
// 返回promise,完成链式
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject){
// 如果循环引用
if(x === promise2){
// reject报错
return reject(new TypeError('Chaining cycle detected for promise'));
}
// 防止多次调用
let called;
// x不是null 且x是对象或者函数
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
// A+规定,声明then = x的then方法
let then = x.then;
// 如果then是函数,就默认是promise了
if (typeof then === 'function') {
// 就让then执行 第一个参数是this 后面是成功的回调 和 失败的回调
then.call(x, y => {
// 成功和失败只能调用一个
if (called) return;
called = true;
// resolve的结果依旧是promise 那就继续解析
resolvePromise(promise2, y, resolve, reject);
}, err => {
// 成功和失败只能调用一个
if (called) return;
called = true;
reject(err);// 失败了就失败了
})
} else {
resolve(x); // 直接成功即可
}
} catch (e) {
// 也属于失败
if (called) return;
called = true;
// 取then出错了那就不要在继续执行了
reject(e);
}
} else {
resolve(x);
}
}
简化版,便于记忆
class Promise{
constructor(executor){
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
let resolve = value => {
if (this.state === 'pending') {
this.state = 'resolved';
this.value = value;
this.onResolvedCallbacks.forEach(fn=>fn());
}
};
let reject = reason => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn=>fn());
}
};
try{
executor(resolve,reject)
}catch(error){
reject(error)
}
}
then(onFulfilled,onRejected) {
// onFulfilled如果不是函数,就忽略onFulfilled,直接返回value
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
// onRejected如果不是函数,就忽略onRejected,直接扔出错误
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
//返回一个新的promise对象实现链式调用
return new Promise((resolve, reject) => {
if (this.state === 'fulfilled') {
let x=onFulfilled(this.value);
resolve(x)
};
if (this.state === 'rejected') {
let x=onRejected(this.reason);
reject(x)
};
if (this.state === 'pending') {
this.onResolvedCallbacks.push(() => {
let x=onFulfilled(this.value);
resolve(x)
});
this.onRejectedCallbacks.push(() => {
let x=onRejected(this.reason);
reject(x)
});
};
});
}
}
let promise1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('我成功执行了')
},1000)
})
promise1.then(onfulFilled=>{
console.log(onfulFilled)
return onfulFilled
}).then().then().then(e=>{
console.log(e)
})
参考自——史上最最最详细的手写Promise教程