话不多说,直接上代码

Promise手写

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function MyPromise(executor){
  let self = this
  self.status='pending'
  self.value=undefined
  self.reason = undefined
  self.fullfilledCallbacks=[]
  self.rejectedCallbacks=[]
  function resolve(value){
     if(self.status==='pending'){
       self.status = 'fullfilled'
       self.value = value
       self.fullfilledCallbacks.forEach(fn=>{
         fn()
       })
     
  }
  function reject(reason){
    if(self.status==='pending'){
      self.status = 'rejected'
      self.reason =reason
      self.rejectedCallbacks.forEach(fn=>[
        fn()
      ])
    }
  }
  try{
    executor(resolve,reject)
  }catch(err){
    reject(err)
  }
}

完善Promise.then

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
MyPromise.prototype.then=function(fn1,fn2){
  let self = this
  let promise2 =new MyPromise(function(resolve,reject){
   if(self.status==='fullfilled'){
    try{
      let x =fn1(self.value)
      resolve(x)
       }catch(e){
         reject(e)
       }
  }
  if(self.status==='rejected'){
        try{
      let x =fn2(self.reason)
      reslove(x)
       }catch(e){
         reject(e)
       }
  }
  if(self.status==='pending'){
    self.fullfilledCallbacks.push(function(){
          try{
          let x =fn1(self.value)
          resolve(x)
       }catch(e){
         reject(e)
       }
    })
    self.rejectedCallbacks.push(function(){
              try{
      let x =fn2(self.reason)
      reslove(x)
       }catch(e){
         reject(e)
       }
    })
  }
  })
}

补充Promise.all

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
myPromise.all=function(arr){
  return new myPromise(function(resolve,reject){
    if(!Array.isArray(arr)){
      throw new Error('arguments must be array')
    }
    let dataArr = []
    let num = 0
    for(let i = 0;i<arr.length;i++){
      let p =arr[i]
      p.then(data=>{
        dataArr.push(data)
        num++
        if(num===arr.length){
          resolve(dataArr)
        }
      }).catch((e)=>{
        reject(e)
      })
  })
}

demo运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let p = new MyPromise(function (resolve, reject) {
  console.log('start')
  setTimeout(function(){
      resolve('data1')
  },2000)
})
p.then(
  (v) => {
    console.log('success: ' + v)
  },
  (v) => {
    console.log('error: ' + v)
  }
)
p.then(
  (v) => {
    console.log('success: ' + v)
  },
  (v) => {
    console.log('error: ' + v)
  }
)
console.log('end')