class myPromise {
constructor(executor) {
this.status = 'pending'
this.value = undefined
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (data) => {
if (this.status === 'pending') {
this.status = 'fulfilled'
this.value = data
console.log(this.onResolvedCallbacks)
this.onResolvedCallbacks.forEach(fn => fn())
}
}
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'
this.value = reason
console.log(this.onRejectedCallbacks)
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : (value) => value
onRejected = typeof onRejected == 'function' ? onRejected : (reason) => { throw reason }
const promise = new myPromise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
try {
const result = onFulfilled(this.value)
this.resolvePromise(promise, result, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
}
if (this.status === 'rejected') {
setTimeout(() => {
try {
const reason = onRejected(this.value)
this.resolvePromise(promise, reason, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
}
if (this.status === 'pending') {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
const result = onFulfilled(this.value)
this.resolvePromise(promise, result, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const reason = onRejected(this.value)
this.resolvePromise(promise, reason, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
})
}
})
return promise
}
resolvePromise(promise, result, resolve, reject) {
if (promise === result) {
return reject('Chaining cycle detected for promise')
}
let called = false
if (result instanceof myPromise) {
result.then((y) => {
if (called) return
called = true
this.resolvePromise(promise, y, resolve, reject)
}, (reason) => {
if (called) return
called = true
reject(reason)
})
return
}
if (result !== null && (typeof result === 'object' || typeof result === 'function')) {
try {
const then = result.then;
if (typeof then === 'function') {
then.call(result, (y) => {
if (called) return
called = true
this.resolvePromise(promise, y, resolve, reject)
}, (reason) => {
if (called) return
called = true
reject(reason)
})
}
} catch (error) {
if (called) return
called = true
reject(error)
}
return
}
resolve(result)
}
static all(promises) {
return new myPromise((resolve, reject) => {
const result = []
promises.forEach((promise, index) => {
promise.then(res => {
result[index] = res
if (index === result.length - 1) {
resolve(result)
}
}, (reason) => {
reject(reason)
})
})
})
}
static race(promises) {
return new myPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject)
})
})
}
static any(promises) {
return new myPromise((resolve, reject) => {
const result = []
const reasons = []
promises.forEach(promise => {
promise.then(res => {
result.push(res)
if (result.length + reason.length === promises.length && result.length) {
resolve(result[0])
}
}, (reason) => {
if (result.length + reason.length === promises.length && !result.length) {
reject(reasons)
}
reason.push(reason)
})
})
})
}
static allSettled(promises) {
return new myPromise((resolve, reject) => {
const result = []
promises.forEach((promise, index) => {
promise.then(res => {
result[index] = res
if (index === result.length - 1) {
resolve(result)
}
}, (reason) => {
result[index] = reason
})
})
})
}
}
new myPromise((resolve, reject) => {
console.log("start");
resolve(100);
})
.then((res) => {
console.log(res, "----------res");
return new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(88888);
}, 1000);
});
})
.then((data) => {
console.log("xixiixi");
console.log(data);
});
console.log("hahhahah");