今天先实现了简洁版的promise
class Promise1 {
static PENDING = "Pending"
static FULFILLED = "Fulfilled"
static REJECTED = "Rejected"
constructor(executor) {
this.initValue()
this.initBind()
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 绑定this值
initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
// 初始化值
initValue() {
this.value = null // 终值
this.reason = null // 拒因
this.state = Promise1.PENDING // 状态
this.onFulfilledCallback = [] // 成功回调
this.onRejectedCallback = [] // 失败回调
}
resolve(value) {
this.value = value
this.state = Promise1.FULFILLED
this.onFulfilledCallback.forEach(fn => fn(this.value))
}
reject(reason) {
this.reason = reason
this.state = Promise1.REJECTED
this.onRejectedCallback.forEach(fn => fn(this.reason))
}
then(onFulfilled, onRejected) {
/**
* 因为这样会有才能穿透,如果不是函数不能直接忽略
* .then()
* .then(val => {
* console.log('value',val) // value 1
* })
*
* */
if (typeof onFulfilled !== 'function') {
onFulfilled = function (value) {
return value
}
}
if (typeof onFulfilled !== 'function') {
onRejected = function (reason) {
return reason
}
}
if (this.state === Promise1.FULFILLED) {
setTimeout(() => {
onFulfilled(this.value)
})
}
if (this.state === Promise1.REJECTED) {
setTimeout(() => {
onRejected(this.reason)
})
}
if (this.state === Promise1.PENDING) {
this.onFulfilledCallback.push(value => {
setTimeout(() => {
onFulfilled(value)
})
})
this.onRejectedCallback.push(reason => {
setTimeout(() => {
onRejected(reason)
})
})
}
}
}
console.log(111)
const promise1 = new Promise1((resolve, rejected) => {
// throw new Error('hahah')
setTimeout(() => {
resolve(222)
})
// rejected(2)
})
promise1.then(result => {
console.log(result, 'result')
}, reason => {
console.log(reason, 'reason')
})
console.log(333)
明天继续后面的实现
3.19补充
class Promise1 {
static PENDING = "Pending"
static FULFILLED = "Fulfilled"
static REJECTED = "Rejected"
static resolvePromise = function (promise2, x, resolve, reject) {
// 循环调用的时候会出现相等的情况
/**
* const p1 = new Promise(resolve => {
resolve(1)
})
const p2 = p1.then(() => {
return p2
})
*/
if (promise2 === x) {
try {
throw new TypeError("Chaining cycle detected for promise")
} catch (e) {
reject(e)
}
}
// 如果 resolvePromise 和 rejectPromise 均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用
let called = false
if (x instanceof Promise1) {
x.then(value => {
Promise1.resolvePromise(x, value, resolve, reject)
}, (reason) => {
reject(reason)
})
} else if (typeof x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then
if (typeof then === 'function') {
// 如果then 由 Object.defineProperty get处理了再返回的,如果处理时出现了错误,则有会抛出异常
then.call(x, value => {
if (called) return
called = true
Promise1.resolvePromise(x, value, resolve, reject)
}, reason => {
if (called) return
called = true
reject(reason)
})
} else {
if (called) return
called = true
resolve(x)
}
} catch (reason) {
if (called) return
called = true
reject(reason)
}
} else {
resolve(x)
}
}
constructor(executor) {
this.initValue()
this.initBind()
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 绑定this值
initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
// 初始化值
initValue() {
this.value = null // 终值
this.reason = null // 拒因
this.state = Promise1.PENDING // 状态
this.onFulfilledCallback = [] // 成功回调
this.onRejectedCallback = [] // 失败回调
}
resolve(value) {
this.value = value
this.state = Promise1.FULFILLED
this.onFulfilledCallback.forEach(fn => fn(this.value))
}
reject(reason) {
this.reason = reason
this.state = Promise1.REJECTED
this.onRejectedCallback.forEach(fn => fn(this.reason))
}
then(onFulfilled, onRejected) {
/**
* 因为这样会有才能穿透,如果不是函数不能直接忽略
* .then()
* .then(val => {
* console.log('value',val) // value 1
* })
*
* */
if (typeof onFulfilled !== 'function') {
onFulfilled = function (value) {
return value
}
}
if (typeof onFulfilled !== 'function') {
onRejected = function (reason) {
return reason
}
}
// 实现链式调用
// then 方法必须返回一个 promise 对象 注3
//promise2 = promise1.then(onFulfilled, onRejected);
let promise2 = new Promise1((resolve, reject) => {
if (this.state === Promise1.FULFILLED) {
setTimeout(() => {
try {
/**
如果 onFulfilled 或者 onRejected 返回一个值 x ,则运行下面的 Promise 解决过程:[[Resolve]](promise2, x)
如果 onFulfilled 或者 onRejected 抛出一个异常 e ,则 promise2 必须拒绝执行,并返回拒因 e
如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值
如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的据因
*/
const x = onFulfilled(this.value)
Promise1.resolvePromise(promise2, x, resolve, reject)
// resolve(x)
} catch (e) {
reject(e)
}
})
}
if (this.state === Promise1.REJECTED) {
setTimeout(() => {
try {
const x = onRejected(this.reason)
Promise1.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
if (this.state === Promise1.PENDING) {
this.onFulfilledCallback.push(value => {
setTimeout(() => {
try {
const x = onFulfilled(value)
Promise1.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
this.onRejectedCallback.push(reason => {
setTimeout(() => {
try {
const x = onRejected(reason)
Promise1.resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
}
})
return promise2
}
}
const p1 = new Promise1(resolve => {
resolve(1)
})
p1
.then(value => {
return new Promise1(resolve => {
resolve(new Promise1(resolve => {
resolve(333)
}))
})
})
.then(value => {
console.log('value', value)
})
如果想要检测自己写的promise是否符合promise A+ 的规范,那么可以按照下面的方式去检测 先全局安装
npm i promises-aplus-tests -g
然后在你写的promise文件最后面写上这段代码
Promise1.defer = Promise1.deferred = function () {
let dfd = {}
dfd.promise = new Promise1((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise1;
最后运行这段就可以检测了,然后根据报错去修改你的promise吧
npx promises-aplus-tests 你的promise文件
参考: 文章 -> Promise A+ 规范【中文版】
视频 -> b站:手摸手教你实现Promise/A+规范