// Promise.resolve().then(() => {
// console.log(0);
// return Promise.resolve(4);
// }).then((res) => {
// console.log(res)
// })
// Promise.resolve().then(() => {
// console.log(1);
// }).then(() => {
// console.log(2);
// }).then(() => {
// console.log(3);
// }).then(() => {
// console.log(5);
// }).then(() => {
// console.log(6);
// })
// 在掘金发现这样一道题,与我心里想的结果并不一样 问大佬 大佬的解释 是下面的这个
/**
* Js引擎为了让microtask尽快的输出,做了一些优化,
* 连续的多个then(3个)如果没有reject或者resolve会交替执行then而不至于让一个堵太久完成用户无响应,
* 不单单v8这样其他引擎也是这样,因为其实promuse内部状态已经结束了。
* 这块在v8源码里有完整的体现,所以说在不同的环境,执行结果是不同的。
* */
// executor:执行器
// value 成功获得的值
// reason:失败的原因
// < !-- 我的手写primose核心 -->
// class Yang {
// // 等待状态
// static PENDING = 'PENDING'
// // 成功状态(满足)
// static FULFILLED = 'FULFILLED'
// // 失败状态
// static REJECTED = 'REJECTED'
// constructor(executor) {
// // 初始状态(等待状态)
// this.status = Yang.PENDING
// // 初始值
// this.value = null
// // 异步的任务队列数组 存放异步时的任务 改变状态的时候在从数组中拿出来执行
// this.callbacks = []
// // 执行器要执行传进来的两个函数中的一个 但是这里有this指向问题
// // 这里要捕获错误因为不知道程序会不会报错
// try {
// executor(this.resolve.bind(this), this.reject.bind(this))
// } catch (error) {
// // 如果程序出现错误也就是被拒绝了
// this.reject(error)
// }
// }
// // 成功的处理函数
// resolve(value) {
// // 改变状态 但是如果状态不是PENDING那就不能改变 状态只可以改变一次
// if (this.status === Yang.PENDING) {
// this.status = Yang.FULFILLED
// this.value = value
// // 这里要执行异步任务数组里的成功的函数
// // 这里要保证promise是异步的
// setTimeout(() => {
// this.callbacks.map(callback => {
// callback.onResolve(value)
// })
// });
// }
// }
// // 失败的处理函数
// reject(reason) {
// // 改变状态 但是如果状态不是PENDING那就不能改变 状态只可以改变一次
// if (this.status === Yang.PENDING) {
// this.status = Yang.REJECTED
// this.value = reason
// // 这里要执行异步任务数组里的失败的函数
// // 这里要保证Promise是异步的
// setTimeout(() => {
// this.callbacks.map(callback => {
// callback.onReject(reason)
// })
// });
// }
// }
// // 然后呢 观察原生的发现调用原生的会传进成功的回调和失败的回调
// then(onResolve, onReject) {
// // 这里有一个问题 then的时候函数并不是必须传的
// // 如果执行了一个空的then说明没有传递参数 那then的穿透就要在这里做
// // 如果啥也没传我封装函数的时候也要帮他把值return出去 别问 问就是我是雷锋
// if (typeof onResolve !== 'function') {
// onResolve = () => this.value
// }
// if (typeof onReject !== 'function') {
// onReject = () => this.value
// }
// // 返回一个Promise 实现链式调用
// return new Yang((resolve, reject) => {
// // then的时候通过判断状态 调用不同的函数
// // 这里要对等待状态进行处理 也就是状态被异步改变了
// if (this.status === Yang.PENDING) {
// // 当状态是等待状态的时候 先把任务压入 异步任务数组
// this.callbacks.push({
// onResolve: value => {
// // 这里要进行错误的处理 还是一样只要失败都交给错误状态的处理函数去处理
// try {
// let result = onResolve(value)
// // 等待阶段也一样
// if (result instanceof Yang) {
// result.then(resolve, reject)
// } else {
// resolve(result)
// }
// } catch (error) {
// reject(error)
// }
// },
// onReject: value => {
// try {
// let result = onReject(value)
// if (result instanceof Yang) {
// result.then(resolve, reject)
// } else {
// resolve(result)
// }
// } catch (error) {
// reject(error)
// }
// }
// })
// }
// // 成功状态
// if (this.status === Yang.FULFILLED) {
// // 满足了调用成功的回调
// // 这里也要处理异常状况 在Promise里只要出现了错误相当于拒绝
// // 直接交给失败的处理函数 并且把失败的信息抛出去
// // 这里要把任务放到异步执行里 因为then是异步的呀
// setTimeout(() => {
// try {
// // 这里要拿到上一次then的返回值 并把下一个then的状态改变为成功的状态 实现链式
// let result = onResolve(this.value)
// // 这里进行判断 如果上一个then返回的是一个Promise
// if (result instanceof Yang) {
// // 就是如果你返回一个promise那我就把值传给你的then
// // 这里无非就是调用的 成功和失败的方法 返回的是一个❤的promise所以可以直接调用他的resolve和reject
// result.then(resolve, reject)
// // result.then(value => {
// // resolve(value)
// // }, reason => {
// // reject(reason)
// // })
// } else {
// resolve(result)
// }
// } catch (error) {
// reject(error)
// }
// });
// }
// // 失败状态
// if (this.status === Yang.REJECTED) {
// // 失败了调用失败的回调
// // 与成功状态一样这里也要处理程序报错的情况
// setTimeout(() => {
// try {
// // 即使上一个then是被拒绝的 那下一次也要坚信成功 追女孩子一样~_~
// // 失败和成功是一样
// let result = onReject(this.value)
// if (result instanceof Yang) {
// result.then(resolve, reject)
// } else {
// resolve(result)
// }
// } catch (error) {
// reject(error)
// }
// });
// }
// })
// }
// }
// ===============================测试代码===========================================
// // 第一阶段测试代码 书写过程中的测试代码
// const yang = new Yang((resolve, reject) => {
// // 成功调用这个改变状态
// // resolve('成功')
// setTimeout(() => {
// resolve('成功')
// // reject('失败')
// }, 1000);
// // 这里发现异步改变状态的时候我的Promise崩了 因为状态是一秒之后被改变的 我只对成功和失败做了处理
// // 解决是在一秒之后的
// // 解决方案回调咯
// // 解决then的链式调用 then返回的一定是一个promise (_**_)
// // 无论第一个promise的状态是什么 后面的promise都是成功的
// }).then() // 这里执行一个空的then 发现自己的值又没了 then没有穿透
// .then(result => {
// // promise一定是异步的
// console.log(result);
// return 2021 // 这里return 发现后面的then接收不到值 ~_~
// }, result => {
// console.log(result);
// return 'hello Promise'
// }).then(result => {
// console.log(1);
// // 这里要接受上一个then的返回值
// console.log(result);
// })
// // console.log(yang);
// console.log('曾经我以为自己很懂Promise'); // 这里发现我的Promise是同步的 所以要加入异步执行队列
// // 原生的Promise有穿透效果 即使上一个then啥也没做也是可以继续向下执行的 then可以穿透
// ===============================测试代码===========================================
// // 第二阶段测试代码 同步成功与异步成功
// new Yang((resolve, reject) => {
// // 测试异步
// setTimeout(() => {
// resolve('第一层Promise成功')
// }, 1000);
// }).then(result => {
// console.log(result);
// return new Yang((resolve, reject) => {
// resolve('第二层Promise')
// })
// // 这里思考如果这个then 返回一个Promise呢?原生的可以返回一个Promse 并且之后可以继续链式调用
// // 也就是说我的Promise里要对then返回的值进行判断然后进行不同的处理
// }, err => {
// console.log(err);
// }).then(result => {
// // 这里理论上是可以拿到第二层Promise的数据的
// console.log(result);
// return '你的力量,让我更加坚强'
// }).then(result => {
// console.log(result);
// })
// ===============================测试代码===========================================
// // 第三阶段测试代码 同步拒绝与异步拒绝
// new Yang((resolve, reject) => {
// // 测试异步
// setTimeout(() => {
// reject('第一层Promise失败')
// }, 1000);
// }).then(null, err => {
// // 拿到第一层失败的结果并返回一个Promise
// console.log(err);
// return new Yang((resolve, reject) => {
// reject('第二层Promise失败')
// })
// }).then(null, err => {
// console.log(err);
// // 测试返回原始值
// return '这些祝福来自与四海八方,来自'
// }).then(result => {
// console.log(result);
// return '给你我最好的自己'
// }).then(result => {
// console.log(result);
// return '编程式套娃成功'
// }).then(result => {
// console.log(result);
// })
// ===============================优化代码===========================================
class Yang {
static PENDING = 'PENDING'
static FULFILLED = 'FULFILLED'
static REJECTED = 'REJECTED'
constructor(executor) {
this.status = Yang.PENDING
this.value = null
this.callbacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
// 成功的处理函数
resolve(value) {
if (this.status === Yang.PENDING) {
this.status = Yang.FULFILLED
this.value = value
setTimeout(() => {
this.callbacks.map(callback => {
callback.onResolve(value)
})
});
}
}
// 失败的处理函数
reject(reason) {
if (this.status === Yang.PENDING) {
this.status = Yang.REJECTED
this.value = reason
setTimeout(() => {
this.callbacks.map(callback => {
callback.onReject(reason)
})
});
}
}
// then方法
then(onResolve, onReject) {
if (typeof onResolve !== 'function') {
onResolve = () => this.value
}
if (typeof onReject !== 'function') {
onReject = () => this.value
}
// 返回一个Promise 实现链式调用
let promise = new Yang((resolve, reject) => {
if (this.status === Yang.PENDING) {
this.callbacks.push({
onResolve: value => {
this.optimizing(promise, onResolve(this.value), resolve, reject)
}, onReject: value => {
this.optimizing(promise, onReject(this.value), resolve, reject)
}
})
}
// 成功状态
if (this.status === Yang.FULFILLED) {
setTimeout(() => {
this.optimizing(promise, onResolve(this.value), resolve, reject)
});
}
// 失败状态
if (this.status === Yang.REJECTED) {
setTimeout(() => {
this.optimizing(promise, onReject(this.value), resolve, reject)
});
}
})
// 返回promise
return promise
}
// 冗余代码的处理
optimizing(promise, result, resolve, reject) {
// console.log(promise);
// console.log(result);
// console.log(resolve);
// console.log(reject);
if (promise == result) {
throw new TypeError('听说你想返回你自己?')
}
try {
if (result instanceof Yang) {
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
}
// ===============================测试优化后代码===========================================
// // 第二阶段测试代码 同步成功与异步成功
// new Yang((resolve, reject) => {
// // 测试异步
// setTimeout(() => {
// resolve('第一层Promise成功')
// }, 1000);
// }).then(result => {
// console.log(result);
// return new Yang((resolve, reject) => {
// resolve('第二层Promise')
// })
// // 这里思考如果这个then 返回一个Promise呢?原生的可以返回一个Promse 并且之后可以继续链式调用
// // 也就是说我的Promise里要对then返回的值进行判断然后进行不同的处理
// }, err => {
// console.log(err);
// }).then(result => {
// // 这里理论上是可以拿到第二层Promise的数据的
// console.log(result);
// return '你的力量,让我更加坚强'
// }).then(result => {
// console.log(result);
// })
// ===============================测试代码===========================================
// 第三阶段测试代码 同步拒绝与异步拒绝
// new Yang((resolve, reject) => {
// // 测试异步
// setTimeout(() => {
// reject('第一层Promise失败')
// }, 1000);
// }).then(null, err => {
// // 拿到第一层失败的结果并返回一个Promise
// console.log(err);
// return new Yang((resolve, reject) => {
// reject('第二层Promise失败')
// })
// }).then(null, err => {
// console.log(err);
// // 测试返回原始值
// return '这些祝福来自与四海八方,来自'
// }).then(result => {
// console.log(result);
// return '给你我最好的自己'
// }).then(result => {
// console.log(result);
// return '编程式套娃成功'
// }).then(result => {
// console.log(result);
// })
// ===============================测试代码===========================================
// let promise = new Yang((resolve, reject) => {
// resolve('解决')
// // reject('kk')
// })
// let p = promise.then(value => {
// // 不能返回自己 为什么可以返回自己 因为then是异步的
// return p
// })
手写Promise
最新推荐文章于 2024-06-20 20:20:21 发布