为了更好的体现Promise的核心实现,已决状态只留resolved
参数值传递
new myPromise(resolve => {
resolve(12)
}).then(data => {
console.log(data)
})
复制代码
看myPromise内需要传一个函数,且该函数的参数还是个函数,即这种形式myPromise(fn(f)),f里有一个参数。之后then中的data会被赋予f中的参数值,then()需要传递一个函数作为参数,而data又是该函数的参数。
要实现这样的数据传递,如何做?
myPromise以类的方式声明
class myPromise {
constructor(excu) {
this.data = 0
let resolve = dat => {
this.data = dat
}
excu(resolve)
}
then(thennable) {
thennable(this.data)
}
}
复制代码
一、值在类中被保存
- 在constructor中,该类需要传递一个函数作为参数,即constructor(excu),excu中有一个resolve函数,最后excu需要在new的时候被执行一次,即excu(resolve)
- 在该类中resolve是没有被定义的,需要定义。形式上resolve有个参数,需要被保存用data保存
二、值传递到then中
- 定义then方法,在then方法传递一个thennable参数
- then方法内,调用thennable(this.data)
且看效果
new myPromise((resolve, reject) => {
resolve(12)
}).then(data => {
console.log(data)
})
//打印出12
复制代码
解释:js中的值传递可以实参到形参,也可以形参到实参,貌似并没有明确的界限,很灵活thennable(this.data),将data值传到了then(data => {console.log(data)})处。
then的链式调用实现
先将代码推到这一步
class myPromise {
constructor(excu) {
this.data = 0
this.status = "pendding"
let resolve = dat => {
if (this.status == "pendding") {
this.data = dat
this.status = "resolved"
}
}
excu(resolve)
}
then(thennable) {
let promise2 = new myPromise(resolve => {
if (this.status == "resolved") {
let x = thennable(this.data)
resolve(x)
}
})
return promise2
}
}
复制代码
加入状态padding和resolved不用多说了,主要看then函数中的变化。
- then返回的得是个promise,因此需要new myPromise,再return。
- thennable是有返回值的,这里不考虑复杂情况,假设返回的仅仅是一个数字。那么该数字即成为下一个promise的data值。
- 用resolve完成关联,注意此处的resolve是new myPromise中的参数,换句话说,resolve是then生成的新promise的,而箭头函数的使用,使得其中的this指向前一个promise,最后resolve(x),将前Promise的data值成功传递到了后Promise的data中
且看效果
new myPromise((resolve, reject) => {
resolve(12)
}).then(data => {
console.log(data)
return data
}).then(data => {
console.log(data + 1)
return data + 1
}).then(data => {
console.log(data + 1)
return data + 1
})
/*打印结果:
12
13
14
*/
复制代码
thennable队列的实现
- myPromise中,padding状态不能执行thennable中的代码
- 切换为resolved状态后,才能执行thennable中的代码
- 采用一个数组进行存储resolved状态要执行的函数
- 在resolve函数中执行先前存储的函数
class myPromise {
constructor(excu) {
this.data = 0
this.status = "pendding"
this.arrayResolve = []
let resolve = dat => {
if (this.status == "pendding") {
this.data = dat
this.status = "resolved"
//将压入arrayResolve的函数拿出运行
this.arrayResolve.forEach(fn => fn())
//其实该数组最多只有一项,也可以使用一下代码执行
// if(this.arrayResolve[0]!=undefined){//也可以try...catch
// this.arrayResolve[0]()
// }
}
}
excu(resolve)
}
then(thennable) {
let promise2 = new myPromise(resolve => {
if (this.status == "resolved") {
console.log("resolved")
//加setTimeout模拟异步
setTimeout(() => {
let x = thennable(this.data)
resolve(x)
}, 0)
}
//添加内容
//如果当前promise状态为pendding,则用存储resolved状态运行的代码。
if (this.status == "pendding") {
console.log("pendding")
this.arrayResolve.push(() => {
setTimeout(() => {
let x = thennable(this.data)
resolve(x)
}, 0)
})
}
})
return promise2
}
}
//测试代码:
new myPromise((resolve, reject) => {
// setTimeout(() => {
resolve(12)
// }, 1)
}).then(data => {
console.log(data)
return data
}).then(data => {
console.log(data + 1)
return data + 1
}).then(data => {
console.log(data + 1)
return data + 1
})
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END