写写Promise
对promise的功能不描述
Promise是构造函数,通过new关键字可以直接获取到实例,且实例可以链式调用then、catch、finally方法,且Promise 自身身上也有 resolve、reject、all、race等方法
/**
* @param {*} executor 执行器函数,此函数有两个形参 resolve和reject
*/
function MyPromise(executor) {
// 添加属性
/** 默认状态 */
this.PromiseState = 'pending'
/** 默认结果值 */
this.PromiseResult = null
// // ??? 因为需要在 MyPromise 中添加属性
// 声明自身的属性
this.callbacks = []
/** 此处需要保存实例对象的 this 的值 */
const _this = this
/** 因为执行器函数中有两个形参,所以此处声明 myResolve 和 myReject */
/** 因为在执行器函数中 调用的 resolve 函数都参数 所以此处需要补充 形参 data */
function myResolve(data) {
/** 因为promise存在状态凝固 所以 在promise的状态发生改变后 就不会再继续执行了 */
if (_this.PromiseState !== 'pending') return
/** 设置对象的状态 [[PromiseState]] */
_this.PromiseState = 'fulfilled' // 或者 resolved
/** 设置对象的结果值 [[PromiseResult]] */
_this.PromiseResult = data
// 异步任务情况下 遍历 .then方法中 保存在 MyPromise 中的 成功的方法
setTimeout(() => {
// 加上 setTimeout 进入 任务队列
_this.callbacks.forEach((itemThen) => {
itemThen.onResolved(data)
})
})
}
/** 因为在执行器函数中 调用的 reject 函数都参数 所以此处需要补充 形参 data */
function myReject(data) {
/** 因为promise存在状态凝固 所以 在promise的状态发生改变后 就不会再继续执行了 */
if (_this.PromiseState !== 'pending') return
/** 设置对象的状态 [[PromiseState]] */
_this.PromiseState = 'rejected'
/** 设置对象的结果值 [[PromiseResult]] */
_this.PromiseResult = data
// 异步任务情况下 遍历 .then方法中 保存在 MyPromise 中的 失败的方法
setTimeout(() => {
// 加上 setTimeout 进入 任务队列
_this.callbacks.forEach((itemThen) => {
itemThen.onRejected(_this.PromiseResult)
})
})
}
try {
// !/** 执行器函数 是同步调用的 */
executor(myResolve, myReject)
} catch (error) {
// 修改 MyPromise 对象状态为失败
myReject(error)
}
}
/**
* then 中有两个参数,一个成功 一个失败
* @param {*} onResolved
* @param {*} onRejected
*/
MyPromise.prototype.then = function (onResolved, onRejected) {
const _this = this
// 处理异常穿透,在then 方法里,如果如果没有第二个方法,来处理异常,我们需要创建一个 reject,来抛出异常 直接赋值给第二个参数
if (typeof onRejected !== 'function') {
onRejected = (reason) => {
throw reason
}
}
// then()的值传递功能
if (typeof onResolved !== 'function') {
onResolved = (value) => value
}
return new MyPromise((resolve, reject) => {
function _callback(cb) {
try {
/** .then 中的resolve中的实参,是通过此处获取到的实例上的实参this.PromiseResult传下去的 */
// 获取 .then 方法中的 resolve 的 Promise结果
const result = cb(_this.PromiseResult)
// 判断result 是否在 MyPromise 的实例上
if (result instanceof MyPromise) {
// 如果在,则根据 MyPromise的then方法中的 Promise对象 的结果进行返回 成功则成功 失败则失败
result.then(
(v) => {
resolve(v)
},
(r) => {
reject(r)
}
)
} else {
// 如果不在,直接返回 成功的 result
resolve(result)
}
} catch (e) {
// 对抛出的异常 直接reject 出去
reject(e)
}
}
/** 通过实例对象的上的状态判断,到底该调用哪个函数 */
if (this.PromiseState === 'fulfilled') {
// 加上 setTimeout 进入 任务队列
setTimeout(() => {
_callback(onResolved)
})
}
/** 通过实例对象的上的状态判断,到底该调用哪个函数 */
if (this.PromiseState === 'rejected') {
// 加上 setTimeout 进入 任务队列
setTimeout(() => {
_callback(onRejected)
})
}
if (this.PromiseState === 'pending') {
// 在此处 把 onResolved/onRejected 保存在 MyPromise callback中
this.callbacks.push({
onResolved: function () {
_callback(onResolved)
},
onRejected: function () {
_callback(onRejected)
},
})
}
})
}
/**
* catch 中只有一个参数,失败的方法
* @param {*} onRejected
*/
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(
(v) => {
resolve(v)
},
(r) => {
reject(r)
}
)
} else {
resolve(value)
}
})
}
MyPromise.reject = function (reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
MyPromise.all = function (promises) {
return new MyPromise((resolve, reject) => {
let count = 0
const arr = []
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(v) => {
count++
arr[i] = v
if (count === promises.length) {
resolve(arr)
}
},
(r) => {
reject(r)
}
)
}
})
}
MyPromise.race = function (promises) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(v) => {
resolve(v)
},
(r) => {
reject(r)
}
)
}
})
}