function MyPromise(fn) {
const pending = 'pending', resolved = 'resolved', rejected = 'rejected'
const that = this
const value = null
const resolvedCallbackList = [], rejectCallbackList = []
that.value = value
that.statusMap = {
pending,
resolved,
rejected
}
that.status = pending
that.resolvedCallbackList = resolvedCallbackList
that.rejectCallbackList = rejectCallbackList
function resolve(v) {
if (that.status === pending) {
if (v instanceof MyPromise) {
return v.then(resolve, reject)
}
that.value = v
that.status = resolved
setTimeout(() => {
that.resolvedCallbackList.forEach(f => {
try {
f(v)
} catch(e) {
reject(e)
}
})
})
}
}
function reject(v) {
if (that.status === pending) {
that.value = v
that.status = rejected
setTimeout(() => {
that.rejectCallbackList.forEach(f => {
try {
f(v)
} catch(e) {
reject(e)
}
})
})
}
}
try {
fn(resolve, reject)
} catch(e) {
reject(e)
}}
MyPromise.prototype.then = function(onFulfilled = v => v, onRejected = err => err) {
const that = this
let newPromise
if (that.status === that.statusMap.pending) {
newPromise = new MyPromise(function(resolve, reject) {
that.resolvedCallbackList.push(() => {
resolve(onFulfilled(that.value))
})
that.rejectCallbackList.push(() => {
reject(onRejected(that.value))
})
})
}
if (that.status === that.statusMap.resolved) {
newPromise = new Promise(function(resolve, reject) {
resolve(onFulfilled(that.value))
})
}
if (that.status === that.statusMap.rejected) {
newPromise = new Promise(function(resolve, reject) {
reject(onRejected(that.value))
})
}
return newPromise
}
MyPromise.all = function promiseAll(promises) {
return new MyPromise(function(resolve, reject) {
var resolvedCounter = 0
var promiseNum = promises.length
var resolvedValues = new Array(promiseNum)
for (let i = 0
promises[i].then(function(value) {
resolvedCounter++
resolvedValues[i] = value
if (resolvedCounter == promiseNum) { // 当所有都变为resolved时
return resolve(resolvedValues)
}
}, function(reason) {
return reject(reason)
})
}
})}
MyPromise.resolve = function(v) {
return new MyPromise(function(res, rej) {
res(v)
})}