跟着coderwhy学习
1.Promise结构的设计
- Promise规范 promisesaplus.com/
const PROMISE_STATUS_PENDING = 'pending'
const PROMISE_STATUS_FULFILLED = 'fulfilled'
const PROMISE_STATUS_REJECTED = 'rejected'
class myPromise {
constructor(executor) {
this.status = PROMISE_STATUS_PENDING
this.value = undefined
this.reason = undefined
const resolve = (value) => {
if (this.status === PROMISE_STATUS_FULFILLED) {
this.status = PROMISE_STATUS_FULFILLED
this.value = value
console.log('resolve被调用')
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_FULFILLED) {
this.status = PROMISE_STATUS_REJECTED
this.reason = reason
console.log("reject被调用")
}
}
executor(resolve, reject)
}
}
const promise = new myPromise((resolve, reject) => {
console.log('状态pending')
resolve(1111)
reject(2222)
})
promise.then(res => {
}, err => {
})
window.onclick = function () {
}
2. then方法设计
...
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
queueMicrotask(() => {
this.value = value
this.onFulfilled(this.value)
});
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
this.status = PROMISE_STATUS_REJECTED
queueMicrotask(() => {
this.reason = reason
this.onRejected(this.reason)
})
}
}
executor(resolve, reject)
}
then(onFulfilled, onRejected) {
this.onFulfilled = onFulfilled
this.onRejected = onRejected
}
}
- then方法设计优化一
class myPromise {
constructor(executor) {
...
this.onFulfilledFns = []
this.onRejectedFns = []
const resolve = (value) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return
this.status = PROMISE_STATUS_FULFILLED
this.value = value
this.onFulfilledFns.forEach(fn => {
fn(this.value)
})
})
}
}
const reject = (reason) => {
if (this.status === PROMISE_STATUS_PENDING) {
// 添加微任务
queueMicrotask(() => {
if (this.status !== PROMISE_STATUS_PENDING) return
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)
}
}
}
- then方法设计优化二
// 工具函数
function execFunctionWithCatchError(execFn, value, resolve, reject) {
try {
const result = execFn(value)
resolve(result)
} catch (err) {
reject(err)
}
}
class myPromise {
constructor(executor) {
...
try {
executor(resolve, reject)
} catch (err) {
reject(err)
}
}
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {
// 1.如果在then调用的时候, 状态已经确定下来
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
// try {
// const value = onFulfilled(this.value)
// resolve(value)
// } catch(err) {
// reject(err)
// }
execFunctionWithCatchError(onFulfilled, this.value, resolve, reject)
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
// try {
// const reason = onRejected(this.reason)
// resolve(reason)
// } catch(err) {
// reject(err)
// }
execFunctionWithCatchError(onRejected, this.reason, resolve, reject)
}
// 2.将成功回调和失败的回调放到数组中
if (this.status === PROMISE_STATUS_PENDING) {
this.onFulfilledFns.push(() => {
// try {
// const value = onFulfilled(this.value)
// resolve(value)
// } catch(err) {
// reject(err)
// }
execFunctionWithCatchError(onFulfilled, this.value, resolve, reject)
})
this.onRejectedFns.push(() => {
// try {
// const reason = onRejected(this.reason)
// resolve(reason)
// } catch(err) {
// reject(err)
// }
execFunctionWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
}
3.catch方法设计
...
catch(onRejected) {
this.then(undefined, onRejected)
}
4.finally方法设计
...
finally(onFinally) {
this.then(() => {
onFinally()
}, () => {
onFinally()
})
}
5.reslove和reject方法设计
...
static resolve(value) {
return new myPromise((resolve) => resolve(value))
}
static reject(reason) {
return new myPromise((resolve, reject) => reject(reason))
}
}
myPromise.resolve("Hello World").then(res => {
console.log("res:", res)
})
myPromise.reject("Error Message").catch(err => {
console.log("err:", err)
})
6.all和allSetted方法设计
static all(promises) {
// 问题关键: 什么时候要执行resolve, 什么时候要执行reject
return new myPromise((resolve, reject) => {
const values = []
promises.forEach(promise => {
promise.then(res => {
values.push(res)
if (values.length === promises.length) {
resolve(values)
}
}, err => {
reject(err)
})
})
})
}
static allSettled(promises) {
return new myPromise((resolve) => {
const results = []
promises.forEach(promise => {
promise.then(res => {
results.push({status: PROMISE_STATUS_FULFILLED, value: res})
if (results.length === promises.length) {
resolve(results)
}
}, err => {
results.push({status: PROMISE_STATUS_REJECTED, value: err})
if (results.length === promises.length) {
resolve(results)
}
})
})
})
}
}
const p1 = new Promise((resolve) => {
setTimeout(() => {
resolve(1111)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2222)
}, 2000)
})
const p3 = new Promise((resolve) => {
setTimeout(() => {
resolve(3333)
}, 3000)
})
// myPromise.all([p1, p2, p3]).then(res => {
// console.log(res)
// }).catch(err => {
// console.log(err)
// })
myPromise.allSettled([p1, p2, p3]).then(res => {
console.log(res)
})
7.rece和any方法设计
static race(promises) {
return new myPromise((resolve,reject) => {
promises.forEach(promises => {
// promise.then(res => {
// resolve(res)
// }, err => {
// reject(err)
// })
promise.then(resolve,reject)
})
})
}
static any(promises) {
// resolve必须等到有一个成功的结果
// reject所有的都失败才执行reject
const reasons = []
return new myPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, err => {
reasons.push(err)
if (reasons.length === promises.length) {
reject(new AggregateError(reasons))
}
})
})
})
}
}
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(1111)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2222)
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(3333)
}, 3000)
})
myPromise.any([p1, p2, p3]).then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err.errors) // [1111, 2222, 3333]
})
简单总结手写Promise
一. Promise规范
二. Promise类设计
class myPromise {}
function myPromise() {}
三.构造函数的规划
class myPromise {
constructor(executor) {
// 定义状态
// 定义resolve、reject回调
// resolve执行微任务队列:改变状态、获取value、then传入执行成功回调
// reject执行微任务队列:改变状态、获取reason、then传入执行失败回调
// try catch
executor(resolve, reject)
}
}
四.then方法的实现
class myPromise {
then(onFullied, onRejected) {
// this.onFulfilled = onFulfilled
// this.onRejected = onRejected
// 1.判断onFulfilled、onRejected,会给默认值
// 2.返回Promise resolve/reject
// 3.判断之前的promise状态是否确定
// onFulfilled/onRejected直接执行(捕获异常)
// 4.添加到数组中push(() => { 执行 onFulfilled/onRejected 直接执行代码})
}
}
五. catch方法
class myPromise {
catch(onRejected) {
return this.then(undefined, onRejected)
}
}
六. finally
class myPromise {
finally(onFinally) {
return this.then(() => {onFinally()}, () => {onFinally()})
}
}
七. resolve/reject
八. all/allSettled
核心:要知道new Promise的resolve、reject在什么情况下执行
all:
- 情况一:所有的都有结果
- 情况二:有一个reject
allSettled:
- 情况:所有都有结果,并且一定执行resolve
九.race/any
race:
- 情况:只要有结果
any:
- 情况一:必须等到一个resolve结果
- 情况二:都没有resolve,所有的都是reject