一、认识Promise
Promise是一个类,可以翻译成 承诺、许诺 、期约
当我们需要给予调用者一个承诺:待会儿我会给你回调数据时,就可以创建一个Promise的对象
二、Promise的状态
待定(pending)
完成(fulfilled)
拒绝(rejected)
一旦状态被确定下来,Promise的状态会被 锁死,该Promise的状态是不可更改的
三、其他promise的API建议自己查询文档,本文只注重功能的实现
四、代码实现步骤:
1、代码结构的简单实现
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED
this.value = value
console.log(this.value, 'resolve被调用了');
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
console.log(this.reason, 'reject被调用了');
}
}
executor(resolve, reject)
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
reject('我是reject')
resolve('我是resolve')
})
2、then方法设计
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
this.value = value
this.onFulfilled(this.value)
console.log(this.value, 'resolve被调用了');
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
this.reason = reason
this.onRejected(this.reason)
console.log(this.reason, 'reject被调用了');
})
}
}
executor(resolve, reject)
}
then(onFulfilled, onRejected) {
this.onFulfilled = onFulfilled
this.onRejected = onRejected
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
resolve('我是resolve')
reject('我是reject')
})
promise.then(res => {
console.log(res, 'res');
}, err => {
console.log(err, 'err');
})
3、then方法优化之-多次调用
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_FULFILLED
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
executor(resolve, reject)
}
then(onFulfilled, onRejected) {
this.onFulfilledFns.push(onFulfilled)
this.onRejectedFns.push(onRejected)
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
reject('我是reject')
resolve('我是resolve')
})
//测试多次调用情况,未做处理时后面代码覆盖前面代码
promise.then(res => {
console.log(res, 'res');
}, err => {
console.log(err, 'err');
})
promise.then(res2 => {
console.log(res2, 'res2');
}, res2 => {
console.log(res2, 'err2');
})
3、then方法优化之-延迟回调的情况
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
executor(resolve, reject)
}
then(onFulfilled, onRejected) {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
onFulfilled(this.value)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
onRejected(this.reason)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(onFulfilled)
this.onRejectedFns.push(onRejected)
}
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
reject('我是reject')
resolve('我是resolve')
})
//在确定Promise状态之后, 再次调用then,但在有延迟的情况下无法加进去,只能打印'状态pending'
setTimeout(() => {
promise.then(res => {
console.log("res3:", res)
}, err => {
console.log("err3:", err)
})
}, 1000)
4、then方法优化之【嵌套】多次调用
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
executor(resolve, reject)
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// onFulfilled(this.value)
try {
const val = onFulfilled(this.value)
resolve(val)
} catch {
}
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
// onRejected(this.reason)
try {
const val = onRejected(this.reason)
resolve(val)
} catch {
}
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilledFns.push(onFulfilled)
// this.onRejectedFns.push(onRejected)
this.onFulfilledFns.push(() => {
try {
const val = onFulfilled(this.value)
resolve(val)
} catch {
}
})
this.onRejectedFns.push(() => {
try {
const val = onRejected(this.reason)
resolve(val) //强调://这个地方也是resolve,只有throw error才会进入下一个reject
} catch {
}
})
}
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
resolve('我是resolve')
reject('我是reject')
})
//then的返回值默认为undefined,如果有具体的返回值也是会转成promise对象,返回值可以继续通过下一个then/catch来接收
//如何实现的:
// 在then方法中return一个promise,将结果resolve出去
promise.then(res => {
console.log("res1:", res)
return "我可以继续往下传下去"
}, err => {
console.log("err1:", err)
return "依旧可以传下去"
}).then(res => {
console.log("res2:", res)
}, err => {
console.log("err2:", err)
})
5、处理promise或者then中抛错的问题
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// onFulfilled(this.value)
try {
const val = onFulfilled(this.value)
resolve(val)
} catch (err) {
reject(err)
}
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
// onRejected(this.reason)
try {
const val = onRejected(this.reason)
resolve(val)
} catch (err) {
reject(err)
}
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilledFns.push(onFulfilled)
// this.onRejectedFns.push(onRejected)
this.onFulfilledFns.push(() => {
try {
const val = onFulfilled(this.value)
resolve(val)
} catch(err) {
reject(err)
}
})
this.onRejectedFns.push(() => {
try {
const val = onRejected(this.reason)
resolve(val) //强调://这个地方也是resolve,只有throw error才会进入下一个reject
} catch (err) {
reject(err)
}
})
}
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
throw new Error("promise中抛错") //promise中抛错
reject('我是reject')
resolve('我是resolve')
})
promise.then(res => {
console.log("res1:", res)
// throw new Error("then抛错") //then抛错
return "我可以继续往下传下去"
}, err => {
console.log("err1:", err)
// throw new Error("then抛错") //then抛错
return "依旧可以传下去"
}).then(res => {
console.log("res2:", res)
}, err => {
console.log("err2:", err)
})
6、try..catch代码过于冗余,抽取公共方法来优化
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
//抽取工具函数
function commonFunc(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// onFulfilled(this.value)
// try {
// const val = onFulfilled(this.value)
// resolve(val)
// } catch (err) {
// reject(err)
// }
commonFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
// onRejected(this.reason)
// try {
// const val = onRejected(this.reason)
// resolve(val)
// } catch (err) {
// reject(err)
// }
commonFunc(onRejected, this.reason, resolve, reject)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilledFns.push(onFulfilled)
// this.onRejectedFns.push(onRejected)
this.onFulfilledFns.push(() => {
// try {
// const val = onFulfilled(this.value)
// resolve(val)
// } catch (err) {
// reject(err)
// }
commonFunc(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
// try {
// const val = onRejected(this.reason)
// resolve(val) //强调://这个地方也是resolve,只有throw error才会进入下一个reject
// } catch (err) {
// reject(err)
// }
commonFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
// throw new Error("promise中抛错") //promise中抛错
reject('我是reject')
resolve('我是resolve')
})
promise.then(res => {
console.log("res1:", res)
throw new Error("then抛错") //then抛错
return "我可以继续往下传下去"
}, err => {
console.log("err1:", err)
throw new Error("then抛错") //then抛错
return "依旧可以传下去"
}).then(res => {
console.log("res2:", res)
}, err => {
console.log("err2:", err)
})
7、实现catch方法
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
//抽取工具函数
function commonFunc(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
//新增catch方法的时候这里要新增几个优化点 - 不做处理会报 execFn is not a function
console.log(onRejected); // undefined 为什么undefined看最下面的解释
const defaultOnRejected = err => {throw err }
onRejected = onRejected || defaultOnRejected
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// onFulfilled(this.value)
// try {
// const val = onFulfilled(this.value)
// resolve(val)
// } catch (err) {
// reject(err)
// }
commonFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
// onRejected(this.reason)
// try {
// const val = onRejected(this.reason)
// resolve(val)
// } catch (err) {
// reject(err)
// }
commonFunc(onRejected, this.reason, resolve, reject)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilledFns.push(onFulfilled)
// this.onRejectedFns.push(onRejected)
this.onFulfilledFns.push(() => {
// try {
// const val = onFulfilled(this.value)
// resolve(val)
// } catch (err) {
// reject(err)
// }
commonFunc(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
// try {
// const val = onRejected(this.reason)
// resolve(val) //强调://这个地方也是resolve,只有throw error才会进入下一个reject
// } catch (err) {
// reject(err)
// }
commonFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
catch(onRejected) {
this.then(undefined,onRejected)
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
// throw new Error("promise中抛错") //promise中抛错
reject('我是reject')
resolve('我是resolve')
})
// promise.then(res => {
// console.log("res:", res)
// },err => {
// }).catch(err => {
// 上面err返回的结果
// })
promise.then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err)
//注意:这个catch是拿不到reject返回出来的值的,他能拿到的是上面的promise的err所返回出来的undefined,他是一个新的promise 相当于new MyPromise.catch()
// 解决:让上面的promise返回出来这个err,catch就能捕获了
// promise1: err => {
// throw err
// }
// promise2: err => {
// }
})
8、实现finally方法
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
//抽取工具函数
function commonFunc(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
//新增catch方法的时候这里要新增几个优化点 - 不做处理会报 execFn is not a function
// console.log(onRejected); // undefined 为什么undefined看最下面的解释
const defaultOnRejected = err => {
throw err
}
onRejected = onRejected || defaultOnRejected
const defaultOnFulfilled = value => {
return value
}
onFulfilled = onFulfilled || defaultOnFulfilled
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
commonFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
commonFunc(onRejected, this.reason, resolve, reject)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled) this.onFulfilledFns.push(() => {
commonFunc(onFulfilled, this.value, resolve, reject)
})
if (onRejected) this.onRejectedFns.push(() => {
commonFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
catch (onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
this.then(() => {
onFinally()
}, () => {
onFinally()
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
// throw new Error("promise中抛错") //promise中抛错
resolve('我是resolve')
reject('我是reject')
})
// 测试一下:
// promise.then(res => {
// }).finally(() => {
// console.log("finally") //finally
// })
//多次调用情况下的finally
promise.then(res => {
console.log("res1:", res)
return '陈非凡'
}, err => {
console.log("err1:", err)
}).then(res2 => {
console.log("res2:", res2)
}).catch(err3 => {
console.log('err3', err3);
}).finally(() => {
console.log('finally');
//Cannot read property 'finally' of undefined 直接这样写会报错原因:需要catch也返回一个promise,在catch方法中 return this.then(undefined, onRejected) 即可
// 注意:catch会阻碍finally打印的情况 onFulfilled = onFulfilled || defaultOnFulfilled 因为resolve的时候的then没有继续处理,没有传到下一步 所以finally没有执行
})
9、实现resolve和reject方法
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
//抽取工具函数
function commonFunc(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
//新增catch方法的时候这里要新增几个优化点 - 不做处理会报 execFn is not a function
// console.log(onRejected); // undefined 为什么undefined看最下面的解释
const defaultOnRejected = err => {
throw err
}
onRejected = onRejected || defaultOnRejected
const defaultOnFulfilled = value => {
return value
}
onFulfilled = onFulfilled || defaultOnFulfilled
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
commonFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
commonFunc(onRejected, this.reason, resolve, reject)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled) this.onFulfilledFns.push(() => {
commonFunc(onFulfilled, this.value, resolve, reject)
})
if (onRejected) this.onRejectedFns.push(() => {
commonFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
catch (onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
this.then(() => {
onFinally()
}, () => {
onFinally()
})
}
static resolve(value) {
return new MyPromise((resolve) => {
resolve(value)
})
}
static reject(reason) {
return new MyPromise((resolve,reject) => {
reject(reason)
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
// throw new Error("promise中抛错") //promise中抛错
resolve('我是resolve')
reject('我是reject')
})
MyPromise.resolve('你好陈非凡').then(res => {
console.log(res);
})
MyPromise.reject('哎呀报错了').catch(err => {
console.log(err);
})
10、Promise.all 和 Promise.allSettled 的实现
区分:
1、all是所有的Promise都变成fulfilled时, 再拿到结果,在拿到所有结果之前, 有一个promise变成了rejected, 那么整个promise是rejected
2、allSettled 无论是resolve还是reject,都有结果才会有最终的状态
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
//抽取工具函数
function commonFunc(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
//新增catch方法的时候这里要新增几个优化点 - 不做处理会报 execFn is not a function
// console.log(onRejected); // undefined 为什么undefined看最下面的解释
const defaultOnRejected = err => {
throw err
}
onRejected = onRejected || defaultOnRejected
const defaultOnFulfilled = value => {
return value
}
onFulfilled = onFulfilled || defaultOnFulfilled
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
commonFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
commonFunc(onRejected, this.reason, resolve, reject)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled) this.onFulfilledFns.push(() => {
commonFunc(onFulfilled, this.value, resolve, reject)
})
if (onRejected) this.onRejectedFns.push(() => {
commonFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
catch (onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
this.then(() => {
onFinally()
}, () => {
onFinally()
})
}
static resolve(value) {
return new MyPromise((resolve) => {
resolve(value)
})
}
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
static all(promiseArr) {
return new MyPromise((resolve, reject) => {
let arr = []
promiseArr.forEach(promise => {
promise.then(res => {
arr.push(res)
if (arr.length === promiseArr.length) {
resolve(arr)
}
}, err => {
reject(err)
})
})
})
}
static allSettled(promiseArr) {
return new MyPromise((resolve, reject) => {
let arr = []
promiseArr.forEach(promise => {
promise.then(res => {
arr.push({
status: PROMISE_STATUS_FULFILLED,
value: res
})
if (arr.length === promiseArr.length) {
resolve(arr)
}
}, err => {
arr.push({
status: PROMISE_STATUS_REJECTED,
value: err
})
if (arr.length === promiseArr.length) {
resolve(arr)
}
})
})
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
// throw new Error("promise中抛错") //promise中抛错
resolve('我是resolve')
reject('我是reject')
})
const p1 = new MyPromise((resolve) => {
setTimeout(() => {
resolve('one')
}, 1000)
})
const p2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('two')
// reject('two')
}, 2000)
})
const p3 = new MyPromise((resolve) => {
setTimeout(() => {
resolve('three')
}, 3000)
})
MyPromise.all([p1, p2, p3]).then(res => {
console.log(res) //全是resolve的话 [ 'one', 'two', 'three' ]
}).catch(err => {
console.log(err) //two
})
MyPromise.allSettled([p1, p2, p3]).then(res => {
console.log(res)
// [{
// status: 'fulfilled',
// value: 'one'
// },
// {
// status: 'fulfilled',
// value: 'two'
// },
// {
// status: 'fulfilled',
// value: 'three'
// }
// ]
})
11、Promise.race 和 Promise.any 的实现
区分:
1、race 只要有一个Promise变成fulfilled状态, 那么就结束
意外: 在都没有结果的时候有一个 先reject了就不等其他结果了,直接算拒绝的
2、any方法 会等到一个fulfilled状态才会决定,但是如果都是reject状态,那么要等到所有都变成reject的
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected' //状态来保证resolve后的reject是无效调用反之亦然
//抽取工具函数
function commonFunc(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
//多次调用需要用数组来接收
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onFulfilled() // this.onFulfilled is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// this.onRejected() // this.onRejected is not a function 代码的执行顺序,这个在then前执行 - 引入微任务解决
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return //由于状态在then写了判断,这里又是异步,所以这里这里要多加一个判断
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
this.onRejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
//抛错处理一:
try {
executor(resolve, reject)
} catch (err) {
reject(err) // 这里可以捕获promise抛错
}
}
//抛错处理二:
then(onFulfilled, onRejected) {
//新增catch方法的时候这里要新增几个优化点 - 不做处理会报 execFn is not a function
// console.log(onRejected); // undefined 为什么undefined看最下面的解释
const defaultOnRejected = err => {
throw err
}
onRejected = onRejected || defaultOnRejected
const defaultOnFulfilled = value => {
return value
}
onFulfilled = onFulfilled || defaultOnFulfilled
return new MyPromise((resolve, reject) => {
// 1.如果在调用then的时候,状态是已经确定的情况
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
commonFunc(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
commonFunc(onRejected, this.reason, resolve, reject)
}
//2.状态未定的时候,将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled) this.onFulfilledFns.push(() => {
commonFunc(onFulfilled, this.value, resolve, reject)
})
if (onRejected) this.onRejectedFns.push(() => {
commonFunc(onRejected, this.reason, resolve, reject)
})
}
})
}
catch (onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
this.then(() => {
onFinally()
}, () => {
onFinally()
})
}
static resolve(value) {
return new MyPromise((resolve) => {
resolve(value)
})
}
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
static all(promiseArr) {
return new MyPromise((resolve, reject) => {
let arr = []
promiseArr.forEach(promise => {
promise.then(res => {
arr.push(res)
if (arr.length === promiseArr.length) {
resolve(arr)
}
}, err => {
reject(err)
})
})
})
}
static allSettled(promiseArr) {
return new MyPromise((resolve, reject) => {
let arr = []
promiseArr.forEach(promise => {
promise.then(res => {
arr.push({
status: PROMISE_STATUS_FULFILLED,
value: res
})
if (arr.length === promiseArr.length) {
resolve(arr)
}
}, err => {
arr.push({
status: PROMISE_STATUS_REJECTED,
value: err
})
if (arr.length === promiseArr.length) {
resolve(arr)
}
})
})
})
}
//只要有一个Promise变成fulfilled状态, 那么就结束 在都没有结果的时候有一个先reject了就不等其他结果了,直接算拒绝的
static race(promiseArr) {
return new MyPromise((resolve, reject) => {
promiseArr.forEach(promise => {
promise.then(resolve, reject)
})
})
}
//会等到一个fulfilled状态才会决定,但是如果都是reject状态,那么要等到所有都变成reject的
static any(promiseArr) {
const arr = []
return new MyPromise((resolve, reject) => {
promiseArr.forEach(promise => {
promise.then(resolve, err => {
arr.push(err)
if (arr.length === promises.length) {
reject(new AggregateError(arr)) //最新es12类型
}
})
})
})
}
}
//实例化
const promise = new MyPromise((resolve, reject) => {
console.log('状态pending');
// throw new Error("promise中抛错") //promise中抛错
resolve('我是resolve')
reject('我是reject')
})
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('one')
}, 3000)
})
const p2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('two')
}, 2000)
})
const p3 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('three')
}, 3000)
})
// MyPromise.race([p1, p2, p3]).then(res => {
// console.log("res:", res)
// }).catch(err => {
// console.log("err:", err) //two
// })
MyPromise.any([p1, p2, p3]).then(res => { //需要去浏览器中测
console.log("res:", res) //two
}, err => {
console.log("err2:", err.errors)
})
暂时就这么多~