class MyPromise{
static PENDING = 'pending';
static FULFILLED = 'fulfilled';
static REJECTED = 'rejected';
constructor(executor){
this.status = MyPromise.PENDING;
this.result = null;
this.onFulfilled = [];// 成功的回调
this.onRejected = [];// 失败的回调
let resolve = result => {
if(this.status === MyPromise.PENDING){
this.status = MyPromise.FULFILLED;
this.result = result;
this.onFulfilled.forEach(fn => fn());
}
}
let reject = result => {
if(this.status === MyPromise.PENDING){
this.status = MyPromise.REJECTED;
this.result = result;
this.onRejected.forEach(fn => fn());
}
}
// 使用try catch 方式实例对象的时候报错 产生异常
try{
executor(resolve, reject);
}catch(err){
this.reject(err);
}
}
// promise执行then的时候可以不传入回调函数,class会给默认的回调函数
then(onFulfilled, onRejected){
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : v => {throw v};
let self = this;
let promise2 = new MyPromise((resolve, reject) => {
const handle = callback => {
setTimeout(() => {
try {
const x = callback(self.result);
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e);
}
})
}
if(self.status === MyPromise.PENDING){
self.onFulfilled.push(handle(onFulfilled));
self.onRejected.push(handle(onRejected));
}
if(self.status === MyPromise.FULFILLED){
handle(onFulfilled);
}
if(self.status === MyPromise.REJECTED){
handle(onRejected);
}
})
}
// promise执行then的时候可以不传入回调函数,class会给默认的回调函数
then2(onFulfilled, onRejected){
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : v => {throw v};
let promise2 = new MyPromise((resolve, reject) => {
if(this.status === MyPromise.PENDING){
self.onFulfilled.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.result);
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e);
}
}, 0);
});
self.onRejected.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.result);
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e);
}
}, 0);
});
}
if(this.status === MyPromise.FULFILLED){
setTimeout(() => {
try {
const x = onFulfilled(this.result);
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e);
}
}, 0);
}
if(this.status === MyPromise.REJECTED){
setTimeout(() => {
try {
const x = onRejected(this.result);
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e);
}
}, 0);
}
})
}
}
function resolvePromise(promise, x, resolve, reject){
if(promise2 === x){
return reject(new TypeError('Chaining cycle detected'));
}
let called;
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;
resolvePromise(promise, y, resolve, reject);
}, e => {
if(called) return;
called = true;
reject(e);
})
}else{
resolve(x);
}
}catch(e){
if(called) return;
called = true;
reject(e);
}
}else {
resolve(x);
}
}
// 这里参数里的resolve 和 reject可以理解为工具,可以修改promise的状态
// 是class自带的工具,因此需要在class中定义
let promise = new MyPromise((resolve, reject) => {});
promise.then(success => {}, err => {});
前端手撕代码——手撕promise
于 2023-06-19 08:51:12 首次发布
文章详细介绍了如何用JavaScript实现一个简易的Promise类,包括状态管理(PENDING,FULFILLED,REJECTED)、回调函数的存储与执行、错误处理以及防止链式调用时的循环引用问题。
摘要由CSDN通过智能技术生成