promise有什么
- promise是一个类,需要传入一个executor执行器,执行器会立即执行
- promise内部有三个状态:pending,resolved,rejected
- promise原型对象上有then,catch函数
- promise函数对象上有all,race,resolve等方法
来实现这些东西
const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"
class Promise {
constructor(executor) {
this.status = PENDING
this.value = undefined
this.reason = undefined
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
let resolve = (value) => {
if (this.status === PENDING) {
this.value = value
this.status = RESOLVED
this.onResolvedCallbacks.forEach((fn) => fn())
}
}
let reject = (reason) => {
if (this.status === PENDING) {
this.reason = reason
this.status = REJECTED
this.onRejectedCallbacks.forEach((fn) => fn())
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onResolved, onRejected) {
onResolved =
typeof onResolved === "function"
? onResolved
: (value) => value
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
throw reason
}
return new Promise((resolve, reject) => {
let resolvePromise = (result) => {
try {
if (result instanceof Promise) {
result.then(resolve, reject)
} else if (
result !== null &&
(typeof result === "object" ||
typeof result === "function")
) {
const then = result.then
if (typeof then === "function") {
then(resolve, reject)
} else {
resolve(then)
}
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (this.status === RESOLVED) {
setTimeout(() => {
let result = onResolved(this.value)
resolvePromise(result)
}, 0)
}
if (this.status === REJECTED) {
setTimeout(() => {
let result = onRejected(this.reason)
resolvePromise(result)
}, 0)
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
let result = onResolved(this.value)
resolvePromise(result)
})
this.onRejectedCallbacks.push(() => {
let result = onRejected(this.reason)
resolvePromise(result)
})
}
})
}
catch(errCallback) {
return this.then(null, errCallback)
}
static all(promises) {
if (!(promises instanceof Array)) {
return Promise.reject(
new Error("params must be a Array!")
)
}
const resultArray = new Array(promises.length)
let resultCount = 0
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
(value) => {
resultCount++
resultArray[index] = value
if (resultCount === promises.length) {
resolve(resultArray)
}
},
(reason) => {
reject(reason)
}
)
})
})
}
static race(promises) {
if (!(promises instanceof Array)) {
return Promise.reject(
new Error("params must be a Array!")
)
}
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
(value) => {
resolve(value)
},
(reason) => {
reject(reason)
}
)
})
})
}
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
}