简单的Promise实现
promise自我介绍
君子一诺千金,承诺的事情一定会做到
promise应用场景
解决回调地狱问题
Promise基本用法
let p=new Promise((resolve,reject)=>{
// resolve('1')
// reject('err')
setTimeout(() => {
resolve('23')
}, 1000);
})
console.log(p)
p.then(response=>{
console.log(response); //23
},err=>{
console.log(err);
})
Promise基本规范
- Promise是立即执行的
- Promise有3种状态,pendding、fulfilld、rejected。pendding-->resolved,pendding-->fulfilld,状态不可逆
- 每一个Promise都有一个then方法
- 如果new Promise报错了会走失败方法reject()
//第一步基础代码
class MyPromise{
constructor(executor){
this.status="pendding"
this.value=""
this.reason=""
try {
executor(this._resolve.bind(this),this._reject.bind(this))
} catch (error) {
this._reject(error)
}
}
_resolve(value){
if(this.status==='pendding'){
this.status="resolved"
this.value=value
}
}
_reject(reason){
if(this.status==='pendding'){
this.status='rejected'
this.reason=reason
}
}
then(onFullFilled,onRejected){
if(this.status==='resolved'){
onFullFilled(this.value)
}
if(this.status==='rejected'){
onRejected(this.reason)
}
}
}
let p1=new MyPromise((resolve,reject)=>{
resolve('1')
// reject('err')
})
p1.then(response=>{
console.log(response);
},err=>{
console.log(err);
})
第一步完成,但是当我们碰到异步调用时,状态就会卡在pendding,不会变成resolved。(根据事件循环机制。执行到then方法时,异步代码里的resolve还没调用,状态就还没变)。此时我们使用一个发布订阅模式。在pendding状态时将成功回调函数和失败的回调函数存到他们各自的数组中去,等到resolve或者reject时,再调用他们。
- 在pendding状态时先收集各回调函数:
then(onFullFilled,onRejected){
if(this.status==='resolved'){
onFullFilled(this.value)
}
if(this.status==='rejected'){
onRejected(this.reason)
}
//异步
if(this.status==='pendding'){
this.onResolvedCallbacks.push(()=>{onFullFilled(this.value)})
this.onRejectedCallbacks.push(()=>{onRejected(this.reason)})
}
}
- 当状态变化的时候就执行发布他们:
_resolve(value){
if(this.status==='pendding'){
this.status="resolved"
this.value=value
//发布
this.onResolvedCallbacks.forEach(fn=>{
console.log('8',fn);
fn()
})
}
}
_reject(reason){
if(this.status==='pendding'){
this.status='rejected'
this.reason=reason
//发布
this.onRejectedCallbacks.forEach(fn=>{
fn()
})
}
}
下面是完整代码:
let p=new Promise((resolve,reject)=>{
// resolve('1')
// reject('err')
setTimeout(() => {
resolve('23')
}, 1000);
})
console.log(p)
p.then(response=>{
console.log(response);
},err=>{
console.log(err);
})
// 1。立即执行
// 2。有resolved、rejected、pendding状态
// 3。then方法有2个参数,可以获得resolve的值
class MyPromise{
constructor(executor){
this.status="pendding"
this.value=""
this.reason=""
this.onResolvedCallbacks=[]
this.onRejectedCallbacks=[]
try {
executor(this._resolve.bind(this),this._reject.bind(this))
} catch (error) {
this._reject(error)
}
}
_resolve(value){
if(this.status==='pendding'){
this.status="resolved"
this.value=value
console.log('7');
this.onResolvedCallbacks.forEach(fn=>{
console.log('8',fn);
fn()
})
console.log('5');
}
}
_reject(reason){
if(this.status==='pendding'){
this.status='rejected'
this.reason=reason
this.onRejectedCallbacks.forEach(fn=>{
fn()
})
}
}
then(onFullFilled,onRejected){
if(this.status==='resolved'){
onFullFilled(this.value)
}
if(this.status==='rejected'){
onRejected(this.reason)
}
if(this.status==='pendding'){
console.log('3',this.value,'-')
this.onResolvedCallbacks.push(()=>{onFullFilled(this.value)})
this.onRejectedCallbacks.push(()=>{onRejected(this.reason)})
}
}
}
let p1=new MyPromise((resolve,reject)=>{
// resolve('1')
// reject('err')
console.log('1')
setTimeout(() => {
console.log('4');
resolve('success')
}, 1000);
})
console.log(p1,2)
p1.then(response=>{
console.log('6');
console.log(response);
},err=>{
console.log(err);
})
你以为到这就大功告成了,额,,这只是个开始,还有then的链式调用,此部分我们下次另说。