Skip to content

Instantly share code, notes, and snippets.

@Messiahhh
Created May 8, 2020 07:42
Show Gist options
  • Select an option

  • Save Messiahhh/38abd959665e3b2fa8243afaeec84150 to your computer and use it in GitHub Desktop.

Select an option

Save Messiahhh/38abd959665e3b2fa8243afaeec84150 to your computer and use it in GitHub Desktop.
Promise的核心实现
class Promise {
constructor(executor) {
if (typeof executor !== 'function') {
throw new TypeError("Promise resolver undefined is not a function")
}
this.status = 'pending'
this.value = undefined
this.onResolvedCallback = []
this.onRejectedCallback = []
const resolve = (value) => {
if (this.status === 'pending') {
if (value instanceof Promise) {
value.then((data) => {
resolve(data)
}, (reason) => {
reject(reason)
})
} else {
this.status = 'fulfilled'
this.value = value
this.onResolvedCallback.forEach(callback => callback())
}
}
}
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'
this.value = reason
this.onRejectedCallback.forEach(callback => callback())
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onResolve, onReject) {
return new Promise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
if (typeof onResolve !== 'function') {
resolve(this.value)
} else {
try {
resolve(onResolve(this.value))
} catch (error) {
reject(error)
}
}
})
}
else if (this.status === 'rejected') {
setTimeout(() => {
if (typeof onReject !== 'function') {
reject(this.value)
} else {
try {
resolve(onReject(this.value))
} catch (error) {
reject(error)
}
}
})
}
else if (this.status === 'pending') {
this.onResolvedCallback.push(() => {
setTimeout(() => {
if (typeof onResolve !== 'function') {
resolve(this.value)
} else {
try {
resolve(onResolve(this.value))
} catch (error) {
reject(error)
}
}
})
})
this.onRejectedCallback.push(() => {
setTimeout(() => {
if (typeof onReject !== 'function') {
reject(this.value)
} else {
try {
resolve(onReject(this.value))
} catch (error) {
reject(error)
}
}
})
})
}
})
}
catch(onReject) {
return this.then(null, onReject)
}
static race(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach((promise) => {
promise.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
})
})
}
static all(promiseArr) {
return new Promise((resolve, reject) => {
let res = []
let length = promiseArr.length
let count = 0
promiseArr.forEach((promise, index) => {
promise.then(value => {
res[index] = value
count++
if (count === length) {
resolve(res)
}
}, (reason) => {
reject(reason)
})
})
})
}
}
// More Infomation / Document
// https://messiahhh.github.io/blog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment