class PromiseM {
static status = {
pendding: 'pendding',
resolved: 'resolved',
rejected: 'rejected'
}
static resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
reject(new TypeError('循环引用'))
}
let called
if (x !== null && (typeof x === 'object') || typeof x === 'function') {
try {
let then = x.then
if (typeof then === 'function') {
then.call(x, (y) => {
if (called) return
called = true
PromiseM.resolvePromise(promise2, y, resolve, reject)
}, (e) => {
if (called) return
called = true
reject(e)
})
} else {
if (called) return
called = true
resolve(x)
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
resolve(x)
}
}
constructor(executor) {
this.status = PromiseM.status.pendding
this.value = undefined
this.reson = undefined
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
let resolve = (value) => {
if (value instanceof PromiseM) {
return value.then(resolve, reject)
}
setTimeout(() => {
if (this.status === PromiseM.status.pendding) {
this.status = PromiseM.status.resolved
this.value = value
this.onFulfilledCallbacks.forEach(cb => cb(this.value))
}
}, 0)
}
let reject = (reson) => {
setTimeout(() => {
if (this.status = PromiseM.status.pendding) {
this.status = PromiseM.status.rejected
this.reson = reson
this.onRejectedCallbacks.forEach(cb => cb(this.reson))
}
}, 0)
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
let promise2 = new PromiseM((resolve, reject) => {
if (this.status === PromiseM.status.pendding) {
this.onFulfilledCallbacks.push(() => {
try {
let x = onFulfilled(this.value)
PromiseM.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
this.onRejectedCallbacks.push(() => {
try {
let x = onRejected(this.reson)
PromiseM.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
if (this.status === PromiseM.status.resolved) {
setTimeout(() => {
try {
let x = onFulfilled(this.value)
PromiseM.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (this.status === PromiseM.status.rejected) {
setTimeout(() => {
try {
let x = onRejected(this.reson)
PromiseM.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
})
return promise2
}
catch(onRejected) {
return this.then(null, onRejected)
}
}
var p = new PromiseM((resolve, reject) => {
resolve('sync')
})
var p1 = p.then((res) => {
console.log(`fulfilled:${res}`)
return { res: res }
}).catch(e => {
console.log(e)
}).then((res) => {
console.log(`p2.fulfilled:${res}`)
})
console