订阅模式实现简单promise
const success = 1, fail = 0 ,pendding = -1;
function MyPromise(deal){
this.status = null
this.freeze = null
Object.defineProperty(this,'status',{
get:function(){
// console.log("get")
return status;
},
set:function(newValue){
// console.log("set")
status = newValue; //通过订阅模式 获取异步执行完成的时机
this.then(this.resolveCallback,this.rejectallback)
},
enumerable : true,
configurable : true
})
console.log(this)
this.status = pendding;
deal(this.resolve.bind(this),this.reject.bind(this))
//使用bind是因为函数作为参数传入函数中 调用者为deal函数 resolve和reject中的 this指向变为window或undefined或者箭头函数获取的this
return this
}
MyPromise.prototype.resolve = function(res) {
if(this.freeze) return
console.log(res)
console.log(this)
this.value = res //value的赋值必须在状态变更之前 不然执行get函数执行then方法时无法获取value
this.freeze = true
this.status = success
};
MyPromise.prototype.reject = function(err) {
if(this.freeze) return
console.log(err)
this.value = err
this.freeze = true
this.status = fail
};
MyPromise.prototype.then = function(resolveCallback,rejectallback) {
//将回调函数储存在this上
this.resolveCallback = resolveCallback
this.rejectallback = rejectallback
if(this.status == -1) return this
// console.log(this.status+"5656459")
// console.log(typeof this.resolveCallback)
//此处status为字符串类型 所以不能使用=== 为什么是字符串类型暂时未知
this.status == 1 && this.resolveCallback && this.resolveCallback(this.value)
this.status == 0 && this.rejectallback && this.rejectallback(this.value)
// setTimeout(()=>{
// console.log(this.status+"5656459")
// // console.log(typeof this.resolveCallback)
// this.status == 1 && this.resolveCallback(this.value)
// this.status == 0 && rejectallback(this.value)
// },0)
return this
};
let a = new MyPromise((resolve)=>{
setTimeout(()=>{ //模拟异步操作
console.log("454")
resolve(78980)
resolve(5656)
},1000)
// new Promise((resolve1)=>{resolve1()}).then(()=>{resolve(456464)})
})
// .then(res=>{console.log(res+"45656")})
//console.log(a.then(res=>{console.log(res+"45656")}).then(res=>{console.log(res+"8888")}))
// 如果连续.then后面的方法会覆盖之前的方法 储存回调函数应该使用数组然后做相应的处理
console.log(a.then(res=>{console.log(res+"45656")}))