1. 最简单版本
const pending = 'pending'
const fulfilled = 'fulfilled'
const rejected = 'rejected'
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch(e){
this.reject(e)
}
}
status = pending
successFunArr = []
failFunArr = []
value = null
reason = null
resolve = (val) => {
if (this.status !== pending) {
return
}
this.value = val
this.status = fulfilled
const size = this.successFunArr.length
queueMicrotask(() => {
for(let i = 0; i< size; i++) {
this.successFunArr[i](val)
}
})
}
reject = (reason) => {
if (this.status !== pending) {
return
}
this.reason = reason
this.status = rejected
const size = this.failFunArr.length
queueMicrotask(() => {
for(let i = 0; i< size; i++) {
this.failFunArr[i](reason)
}
})
}
then = (onFulfilled, onRejected) => {
const onFulfilledCallback = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const onRejectedCallback = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
return new MyPromise(() => {
if (this.status === fulfilled) {
queueMicrotask(() => {
onFulfilledCallback(this.value)
})
} else if (this.status === rejected) {
queueMicrotask(() => {
onRejectedCallback(this.reason)
})
} else {
this.successFunArr.push(onFulfilledCallback)
this.failFunArr.push(onRejectedCallback)
}
})
}
catch = (onRejected) => {
const onRejectedCallback = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
this.failFunArr.push(onRejectedCallback)
}
}
const aP = new MyPromise((resolve, reject) => {
console.log(1)
setTimeout(() => {
resolve(100)
}, 3000)
})
aP.then((v) => {
console.log('MyPromise', v)
})
console.log(2)
2. then返回一个Promise
const pending = 'pending'
const fulfilled = 'fulfilled'
const rejected = 'rejected'
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch(e){
this.reject(e)
}
}
status = pending
successFunArr = []
failFunArr = []
value = null
reason = null
resolve = (val) => {
if (this.status !== pending) {
return
}
this.value = val
this.status = fulfilled
const size = this.successFunArr.length
queueMicrotask(() => {
for(let i = 0; i< size; i++) {
this.successFunArr[i](val)
}
})
}
reject = (reason) => {
if (this.status !== pending) {
return
}
this.reason = reason
this.status = rejected
const size = this.failFunArr.length
queueMicrotask(() => {
for(let i = 0; i< size; i++) {
this.failFunArr[i](reason)
}
})
}
then = (onFulfilled, onRejected) => {
const onFulfilledCallback = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const onRejectedCallback = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
return new MyPromise((resolve, reject) => {
if (this.status === fulfilled) {
queueMicrotask(() => {
try {
let x = onFulfilledCallback(this.value)
resolve(x)
} catch(e){
reject(e)
}
})
} else if (this.status === rejected) {
queueMicrotask(() => {
try {
let x = onRejectedCallback(this.reason)
resolve(x)
} catch(e){
reject(e)
}
})
} else {
this.successFunArr.push((val) => {
try {
let x = onFulfilledCallback(val)
resolve(x)
} catch(e){
reject(e)
}
})
this.failFunArr.push((reason) => {
try {
let x = onRejectedCallback(reason)
resolve(x)
} catch(e){
reject(e)
}
})
}
})
}
catch = (onRejected) => {
return this.then(null, onRejected)
}
}
const aP = new MyPromise((resolve, reject) => {
console.log(1)
setTimeout(() => {
resolve(100)
}, 3000)
})
aP.then((v) => {
console.log('MyPromise 1', v)
return v+ 100
}).then((v) => {
console.log('MyPromise 2', v)
})
console.log(2)