所有代码示例
首先我们要手写一个promise,首先要了解他的用法
const p =new Promise((resolve,reject)=>{
fn1();
resolve()
reject()
})
p.then(resolve(),reject())
所以首先我们先声明一个class Promise
class Promise{
constructor(fn){
const resolve=()=>{}
const reject=()=>{}
fn(resolve,reject)
}
}
然后实现他的.then方法,由于then里面会传一个resolve(),reject(),所以用s代表resolve(),e代表reject(),那么我们如何把then里面的函数传给resolve呢,这里面需要用到队列,所以声明一个queque,为了让resolve和then都能获取,所以声明为成员属性
class Promise{
queue1 =[]
queue2=[]
constructor(fn){
const resolve=()=>{
console.log(this.queue1)
}
const reject=()=>{}
fn(resolve,reject)
}
then(s,e){
this.queue1.push(s)
this.queue2.push(e)
}
}
这时候打印的this.queue1为一个[],但是如果展开看,里面有一个0然后是then(resolve())里面的resolve函数,这是因为resolve是一个异步函数,一开始并不能直接获取,所以是[],那么就需要我们把resolve手动的写成异步函数,所以用setTimeout
class Promise{
queue1 =[]
queue2=[]
constructor(fn){
const resolve=()=>{
setTimeout(()=>{
//console.log(this.queue1[0])
this.queue1[0]()
},0)
}
const reject=()=>{
setTimeout(()=>{
//console.log(this.queue2[0])
this.queue2[0]()
},0)
}
fn(resolve,reject)
}
then(s,e){
this.queue1.push(s)
this.queue2.push(e)
}
}
从打印的内容可以看出
this.queue1[0]是一个函数,需要用this.queue1[0]()调用
这时候就可以使用下面的代码进行测试了
let p=new Promise((resolve,reject)=> {console.log('h1');if(Math.random()>0.5){
resolve()
}else{
reject()
}})
p.then(()=>{console.log('成功')},()=>{console.log('失败')})
若是想实现链式结构,则需要在then函数里面返回this,然后循环queue队列
p.then(()=>{console.log('成功')},()=>{console.log('失败')}).then(()=>{console.log('成功2')},()=>{console.log('失败2')})
class Promise{
queue1 =[]
queue2=[]
constructor(fn){
const resolve=()=>{
setTimeout(()=>{
//console.log(this.queue1[0])
for(let i=0;i<this.queue1.length;i++){
this.queue1[i]()
}
},0)
}
const reject=()=>{
setTimeout(()=>{
//console.log(this.queue2[0])
for(let i=0;i<this.queue2.length;i++){
this.queue2[i]()
}
},0)
}
fn(resolve,reject)
}
then(s,e){
this.queue1.push(s)
this.queue2.push(e)
return this
}
}