Appearance
Promise A+实现
js
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function resolvePromise(promise2, x, resolve, reject) {
// 如果then返回的promise和x是同一个,那么就会造成死循环
if(promise2 === x) {
return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'))
}
if((typeof x === 'object' && x !== null) || (typeof x === 'function')) {
let called = false
try {
const then = x.then
if(typeof then === 'function') {
then.call(x, y => {
if(called) return
called = true
resolvePromise(promise2, y, resolve, reject)
}, e => {
if(called) return
called = true
reject(e)
})
}else {
resolve(x)
}
}catch(e) {
if(called) return
called = true
reject(e)
}
}else {
resolve(x)
}
}
class Promise {
constructor(executor) {
this.status = PENDING
this.value = undefined
this.reason = undefined
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
const resolve = (value) => {
if(value instanceof Promise) {
return value.then(resolve, reject)
}
if(this.status === PENDING) {
this.status = FULFILLED
this.value = value
this.onResolvedCallbacks.forEach(fn => fn(this.value))
}
}
const reject = (reason) => {
if(this.status === PENDING) {
this.status = REJECTED
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
try {
executor(resolve, reject)
}catch(e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
const promise2 = new Promise((resolve, reject) => {
if(this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
queueMicrotask(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push(() => {
queueMicrotask(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
// resolvePromise(promise2, x, resolve, reject)
})
})
}else if(this.status === FULFILLED) {
queueMicrotask(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
})
}else if(this.status === REJECTED){
queueMicrotask(() => {
try {
let x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject)
}catch(e) {
reject(e)
}
// resolvePromise(promise2, x, resolve, reject)
})
}
})
return promise2
}
}
Promise A+测试
npm insall promises-aplus-tests -g
js
// 在实现的promise最下面添加这段函数
Promise.deferred = function(){
let dfd = {}
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject
})
return dfd
}
module.exports = Promise
执行命令 promises-aplus-tests promise.js
Promise方法实现
catch方法实现
js
class Promise {
...
catch(onRejected) {
// 利用promise透传的特性
return this.then(null, onRejected)
}
}
resolve方法实现
js
class Promise {
constructor(executor) {
...
const resolve = value => {
// 如果resolve的是一个promise 调用该promise的then
if(value instanceof Promise) {
return value.then(resolve, reject)
}
...
}
}
...
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
}
reject方法实现
js
class Promise {
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
}
all方法实现
js
class Promise {
...
static all(arr) {
let len = arr.length
const ret = []
return new Promise((resolve, reject) => {
arr.forEach((item, index) => {
Promise.resolve(item).then(data => {
ret[index] = data
if(--len === 0) resolve(ret)
}, reject)
})
})
}
}
race方法实现
js
class Promise {
...
static race(arr) {
return new Promise((resolve, reject) => {
arr.forEach((item, index) => {
Promise.resolve(item).then(resolve, reject)
})
})
}
}