12 手撸promise
如何实现Promise异步调用?如何实现Promise链式调用,其实真理就在其中,我简单按照我的网上理解简单写了一下…
class testPromise{
#status //定义私有变量
#itSuccess='FULFILLED'
#itError = 'REJECTED'
#itWait = 'PENDING' //定义初始化变量
#theValue = null
constructor(executor){
if(typeof executor !=='function' ){
throw new Error("testPromise must accept a function as a param")
}
// 首先的有这个状态
this.#status = this.#itWait
const resolve = value=>{
//进来后状态改变
if(this.#status!==this.#itWait) return
this.#status = this.#itSuccess
this.#theValue = value
}
const reject = value=>{
if(this.#status!==this.#itWait) return
this.#itWait = this.#itError
this.#theValue = value
}
executor(resolve,reject)
}
then(onFulfilled,onReject){
if(this.#status==this.#itSuccess){
onFulfilled(this.#theValue)
}
if(this.#status==this.#itError){
onReject(this.#theValue)
}
}
catch(onRejected){
//直接调用上面的
this.then(null,onRejected)
}
}
let one = new testPromise((resolve,reject)=>{
resolve("resolve")
console.log("加载了resolve")
reject("reject")
})
one.then(res=>{
console.log(res)
},err=>{
console.log(err)
})
console.log("按道理应该先执行我") //但是没有
//现在就是完成了简单了promise
接下来就是解决上面的异步,想到异步我们就想到什么,
- setTimeout
相当于是一个异步任务,.then执行是等resolve或者reject之后才执行,什么情况下能控制他们在以后执行,,任务队列!!!
就是我不管你什么时候resolve,或者reject ,.then的时候我先把这个执行函数放到任务队列里面 ,等 reject,和resolve时再调用
class testPromise{
#status
#itSuccess='FULFILLED'
#itError = 'REJECTED'
#itWait = 'PENDING'
#theValue = null
//2.0解决异步加入
#onFulfilledCalArr = []
#onRejectedCalArr = []
constructor(executor){
if(typeof executor !=='function' ){
throw new Error("testPromise must accept a function as a param")
}
// 首先的有这个状态
this.#status = this.#itWait
const resolve = value=>{
//进来后状态改变
if(this.#status!==this.#itWait) return
this.#status = this.#itSuccess
this.#theValue = value
//2.0加入
this.#onFulfilledCalArr.forEach(fn=>fn())
}
const reject = value=>{
if(this.#status!==this.#itWait) return
this.#itWait = this.#itError
this.#theValue = value
//2.0加入
this.#onRejectedCalArr.forEach(fn=>fn())
}
executor(resolve,reject)
}
then(onFulfilled,onReject){
//2.0加入
setTimeout(()=>{
//成功态
if(this.#status==this.#itSuccess){
onFulfilled(this.#theValue)
}
//失败态
else if(this.#status==this.#itError){
onFulfilled(this.#theValue)
}
//等待态 因为这里可能在promise里面可能还有定时的时候
else{
this.#onFulfilledCalArr.push(()=>onFulfilled(this.#theValue)) //加入队列里面
this.#onRejectedCalArr.push(()=>onReject(this.#theValue))
}
},0)
}
catch(onRejected){
//直接调用上面的
this.then(null,onRejected)
}
}
let one = new testPromise((resolve,reject)=>{
console.log("第一个执行")
setTimeout(()=>{
resolve("时间延迟1s进行resolve我应该是最后一个执行")
reject("在resolve后面 不会执行的")
})
})
one.then(res=>{
console.log(res)
console.log("里面res微任务后执行")
},err=>{
console.log(err)
console.log("reject不会执行的")
})
console.log("外面宏任务先执行")
这样就完成了任务异步执行,所以解决关键点就是在任务数组里面插入函数,需要执行时才执行
最后一个是什么?是不是链式执行
链式?这里自己链式下去,也就是说,自己还能接着调用自己,也就是说 then里面返回的也是promise咯,那就在异步的情况上加呗
class testPromise {
#status
#itSuccess = 'FULFILLED'
#itError = 'REJECTED'
#itWait = 'PENDING'
#theValue = null
//2.0解决异步加入
#onFulfilledCalArr = []
#onRejectedCalArr = []
constructor(executor) {
if (typeof executor !== 'function') {
throw new Error("testPromise must accept a function as a param")
}
// 首先的有这个状态
this.#status = this.#itWait
const resolve = value => {
//进来后状态改变
if (this.#status !== this.#itWait) return
this.#status = this.#itSuccess
this.#theValue = value
//2.0加入
this.#onFulfilledCalArr.forEach(fn => fn())
}
const reject = value => {
if (this.#status !== this.#itWait) return
this.#itWait = this.#itError
this.#theValue = value
//2.0加入
this.#onRejectedCalArr.forEach(fn => fn())
}
executor(resolve, reject)
}
then(onFulfilled, onReject) {
//3.0 链式加入
return new testPromise((resolve, reject) => {
//实行异步
setTimeout(() => {
//成功态
if (this.#status == this.#itSuccess) {
let returnVal = onFulfilled(this.#theValue) //成功态去看返回的是什么值
/** new Promise(resolve=>{
resolve(1)
}).then(res=>{
return new Promise(resolve=>{
})
})
*/
if (returnVal instanceof testPromise) { //如上情形
returnVal.then(resolve, reject) //此时就得提前调用then 把这些函数存进任务队列
} else {
//普通值直接就去执行了
resolve(returnVal)
}
}
//失败态
else if (this.#status == this.#itError) {
let returnVal = onReject(this.#theValue)
if (returnVal instanceof testPromise) {
returnVal.then(resolve, reject) //如上
} else {
reject(returnVal)
}
}
else {
//这个就是直接把上面去两种情况加入到任务队列里面去
//成功函数
let resolveFn = () => {
let returnVal = onFulfilled(this.#theValue) //成功态去看返回的是什么值
if (returnVal instanceof testPromise) { //如上情形
returnVal.then(resolve, reject) //此时就得提前调用then 把这些函数存进任务队列
} else {
//普通值直接就去执行了
resolve(returnVal)
}
}
//失败函数
let rejectFn = () => {
let returnVal = onReject(this.#theValue)
if (returnVal instanceof testPromise) {
returnVal.then(resolve, reject) //如上
} else {
reject(returnVal)
}
}
this.#onFulfilledCalArr.push(resolveFn)
this.#onRejectedCalArr.push(rejectFn)
}
},0)
})
// //2.0加入
// setTimeout(() => {
// //成功态
// if (this.#status == this.#itSuccess) {
// onFulfilled(this.#theValue)
// }
// //失败态
// else if (this.#status == this.#itError) {
// onFulfilled(this.#theValue)
// }
// //等待态 因为这里可能在promise里面可能还有定时的时候
// else {
// this.#onFulfilledCalArr.push(() => onFulfilled(this.#theValue)) //加入队列里面
// this.#onRejectedCalArr.push(() => onReject(this.#theValue))
// }
// }, 0)
}
catch(onRejected) {
//直接调用上面的
this.then(null, onRejected)
}
}
let one = new testPromise((resolve, reject) => {
console.log("第一个执行")
setTimeout(() => {
resolve("时间延迟1s进行resolve我应该是最后一个执行")
reject("在resolve后面 不会执行的")
},1000)
})
one.then(res => {
console.log(res)
console.log("里面res微任务后执行")
return "返回了一个简单字符" //这里进行返回一个字符
}, err => {
console.log(err)
console.log("reject不会执行的")
}).then(res=>{ //再次调用then
console.log("再次接收上面then里面返回的值")
console.log(res)
},err=>{
console.log(err)
})
console.log("外面宏任务先执行")
下面是对照组
let two = new Promise((resolve,reject)=>{
console.log("第一个执行")
setTimeout(() => {
resolve("时间延迟1s进行resolve我应该是最后一个执行")
reject("在resolve后面 不会执行的")
},1000)
})
//对照组,,
two.then(res => {
console.log(res)
console.log("里面res微任务后执行")
return "返回了一个简单字符"
}, err => {
console.log(err)
console.log("reject不会执行的")
}).then(res=>{
console.log("再次接收上面then里面返回的值")
console.log(res)
},err=>{
console.log(err)
})
console.log("外面宏任务先执行")
所以简单的promise就完成啦,后面就剩下all,和race了啦!简单做个记录咯~