tPromise.js
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class TPromise {
constructor(execute) {
this.status = PENDING
this.value = null
this.reason = null
this.onResolvedArray = []
this.onRejectedArray = []
const resolve = (value) => {
setTimeout(() => {
if (this.status === PENDING) {
this.value = value
this.status = FULFILLED
this.onResolvedArray.forEach(func => func(value))
}
})
}
const reject = (reason) => {
setTimeout(() => {
if (this.status === PENDING) {
this.reason = reason
this.status = REJECTED
this.onRejectedArray.forEach(func => func(reason))
}
})
}
try {
execute(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
let promise // 作为 then 函数的返回值
if (this.status === FULFILLED) {
return promise = new TPromise((resolve, reject) => {
setTimeout(() => {
try {
let result = onResolved(this.value)
resolvePromise(promise, result, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
if (this.status === REJECTED) {
return promise = new TPromise((resolve, reject) => {
setTimeout(() => {
try {
let result = reject(this.reason)
resolvePromise(promise, result, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
if (this.status === PENDING) {
return promise = new TPromise((resolve, reject) => {
this.onResolvedArray.push(() => {
try {
let result = onResolved(this.value)
resolvePromise(promise, result, resolve, reject)
} catch (e) {
reject(e)
}
})
this.onRejectedArray.push(() => {
try {
let result = onRejected(this.reason)
resolvePromise(promise, result, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
}
catch(onRejected) {
this.then(undefined, onRejected)
}
}
const resolvePromise = (promise, result, resolve, reject) => {
// 当 result 和 promise 相等时,也就是说 onResolved 返回 promise 时,进行 reject
if (result === promise) reject(new TypeError('ERRROR DUE TO CIRCULAR REFERENCE'))
// 是否已经执行过 onResolved 或者 onRejected
let consumed = false, thenable
if (result instanceof TPromise) {
if (result.status === PENDING) {
result.then(function (data) { resolvePromise(promise, data, resolve, reject) })
} else {
result.then(resolve, reject)
}
return
}
let isComplexResult = target => (typeof target === 'function' || typeof target === 'object') && (target !== null)
// 如果返回的是疑似 Promise 类型
if (isComplexResult(result)) {
try {
thenable = result.then
// 如果返回 Promise 类型,具有 then 方法
if (typeof thenable === 'function') {
thenable.call(result, function (data) {
if (consumed) return
consumed = true
return resolvePromise(promise, data, resolve, reject)
}, function (error) {
if (consumed) return
consumed = true
return reject(error)
})
} else resolve(result)
} catch (e) {
if (consumed) return
consumed = true
return reject(e)
}
} else resolve(result)
}
module.export = { TPromise }
tPromiseTest.js
const TPromise = require("./tPromise")
let promise = new TPromise((resolve, reject) => {
setTimeout(() => { resolve('hello') }, 1000)
setTimeout(() => { reject('hello') }, 2000)
})
promise
.then((data) => {
console.log(data, 1)
return data + ' then1'
})
.then((resolve) => {
console.log(resolve)
}, (reject) => {
console.log(reject)
return reject
})
.catch((err) => console.log(err))