class MyPromise {
constructor (executor) {
this.state = 'pending'
this.value = this.reason = undefined
this.onFulfilledCallback = []
this.onRejectedCallback = []
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
resolve = value => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
this.onFulfilledCallback.forEach(cb => cb())
}
}
reject = reason => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
this.onRejectedCallback.forEach(cb => cb())
}
}
then = (onFulfilled, onRejected) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r }
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
}
if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
}
if (this.state === 'pending') {
this.onFulfilledCallback.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
}, 0)
})
this.onRejectedCallback.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error)
}
})
})
}
})
return promise2
}
catch = fn => this.then(void 0, fn)
}
MyPromise.resolve = value => new MyPromise(resolve => resolve(value))
MyPromise.reject = reason => new MyPromise((resolve, reject) => reject(reason))
MyPromise.race = fnArr => {
return new MyPromise((resolve, reject) => {
fnArr.forEach(fn => {
fn().then(resolve, reject)
})
})
}
MyPromise.all = fnArr => {
const result = []
const index = 0
return new MyPromise((resolve, reject) => {
fnArr.forEach((fn, i) => {
fn().then((v) => {
result[i] = v
index++
if (index === fnArr.length) {
resolve(result)
}
}, reject)
})
})
}
function resolvePromise (promise2, x, resolve, reject) {
if (x === promise2) {
reject(new TypeError('Chaining cycle detected for promise'))
}
// 锁
let called
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then
if (typeof then === 'function') {
then.call(x, y => {
if (called) return
called = true
resolvePromise(promise2, y, resolve, reject)
}, err => {
if (called) return
called = true
reject(err)
})
} else {
resolve(x)
}
} catch (error) {
if (called) return
called = true
reject(error)
}
} else {
resolve(x)
}
}
手写一个符合promise A+规范的promsie
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Promise的基本概念: Promise使异步脱离了回调地狱,可以更优雅的操作异步函数的执行结果。究其根本,不过...
- 写在前面 没错,这又是一篇关于手写 Promise 的文章,想必大家已经看过很多相关 Promise 的文章,关于...
- Promise 实现一个符合 Promise/A+ 规范的 MyPromise,并实现 resolve、rejec...
- Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 ES6 中采用了 Promise/...