Promise的含义

Promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件,更合理和更强大。

Promise实现过程

一实现resolve和reject输出

//4 定义常量(成功使用fulfilled 失败使用rejected 等待使用pending)
let PENDING = 'pending';
let FULFILLED = 'fulfilled';
let REJECTED = 'rejected';
//1 创建一个MyPromise类
class MyPromise{
  //初始化status 状态为pending
  status = PENDING;
  //6.MyPromise类中定义value和reason,用来储存执行器执行成功和失败的返回值
  value= null;
  reason = null;
  //2 通过构造函数constructor,在执行这个类的时候传递一个执行器并立即执行
  constructor(executor){
    executor(this.resolve, this.reject)
  }  
  //3 定义resolve和reject方法
  //5.完成resolve和reject函数的状态改变(需要判断状态是否可以改变)
  resolve=(value) =>{
    if(this.status !== PENDING) return;
    this.status = FULFILLED;
    console.log("resolve=>",value) //resolve=> 成功
    this.value = value;
  }
  reject = (reason)=>{
    if(this.status !== PENDING) return;
    this.status = REJECTED;
    console.log("reject =>",reason) //reject => 失败
    this.reason = reason;
  }    
}

const promise = new MyPromise((resolve,reject)=>{
  resolve("成功")
  //reject('失败')
})

二,实现简单的then方法

1实现简单的then

//7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
  then(onFulfilled, onRejected){
    if(this.status === FULFILLED){
      onFulfilled(this.value)
    }
    if(this.status === REJECTED){
      onRejected(this.reason)
    }
  }

const promise = new MyPromise((resolve,reject)=>{
  //resolve("成功")
  reject('失败')
})
promise.then(value=>{
  console.log("1",value)  //1 成功
},reason=>{
  console.log("2",reason) //2 失败
})

2处理定时器的情况,导致promise没有输出值

const promise = new MyPromise((resolve,reject)=>{
  setTimeout(()=>{
    resolve("成功")
  },2000)
  //reject('失败')
})
promise.then(value=>{
  console.log("1",value)
},reason=>{
  console.log("2",reason)
})
//4 定义常量(成功使用fulfilled 失败使用rejected 等待使用pending)
let PENDING = 'pending';
let FULFILLED = 'fulfilled';
let REJECTED = 'rejected';
//1 创建一个MyPromise类
class MyPromise{
  //初始化status 状态为pending
  status = PENDING;
  //6.MyPromise类中定义value和reason,用来储存执行器执行成功和失败的返回值
  value= null;
  reason = null;
  //9.实现then方法多次调用添加多个处理函数 初始化回调为数组依次执行
  fulfilledCallacks = []
  rejectedCallbacks = [];
  //2 通过构造函数constructor,在执行这个类的时候传递一个执行器并立即执行
  constructor(executor){
    executor(this.resolve, this.reject)
  }  
  //3 定义resolve和reject方法
  //5.完成resolve和reject函数的状态改变(需要判断状态是否可以改变)
  resolve=(value) =>{
    if(this.status !== PENDING) return;
    this.status = FULFILLED;
    console.log("resolve=>",value) //成功
    this.value = value;
    this.fulfilledCallacks.forEach((onFulfilled)=>{
      onFulfilled()
    })
  }
  reject = (reason)=>{
    if(this.status !== PENDING) return;
    this.status = REJECTED;
    console.log("reject =>",reason) //失败
    this.reason = reason;
    this.rejectedCallbacks.forEach((onRejected)=>{
      onRejected()
    })
  }   
  //7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
  then(onFulfilled, onRejected){
    // 8.处理异步逻辑(pending状态下在then中将回调存起来)
    if(this.status === PENDING){
      this.fulfilledCallacks.push(()=>{
        onFulfilled(this.value)
      })
      this.rejectedCallbacks.push(()=>{
        onRejected(this.reason)
      })
    }
    if(this.status === FULFILLED){
      onFulfilled(this.value)
    }
    if(this.status === REJECTED){
      onRejected(this.reason)
    }
  }
}

const promise = new MyPromise((resolve,reject)=>{
  setTimeout(()=>{
    resolve("成功")
    //reject('失败')
  },2000)
  
})

promise.then(value=>{
  console.log("1",value)
},reason=>{
  console.log("2",reason)
})

三 then方法链式调用

1 简单的链式调用

//7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
  then(onFulfilled, onRejected){
    // 10. 实现then方法链式调用(写一个函数方法专门判断回调的结果是普通值还是promise,then方法返回的仍然是一个promise)
    let promise2 = new MyPromise((resolve,reject)=>{
      // 8.处理异步逻辑(pending状态下在then中将回调存起来)
      if(this.status === FULFILLED){
        let x = onFulfilled(this.value);
        resolve(x)
      }else if(this.status === REJECTED){
        let x = onRejected(this.reason)
        reject(x)
      }else{
        this.fulfilledCallacks.push(()=>{
          let x = onFulfilled(this.value);
          resolve(x)
        })
        this.rejectedCallbacks.push(()=>{
          let x = onRejected(this.reason)
          reject(x)
        })
      }
    })
    return promise2
  }

const promise = new MyPromise((resolve,reject)=>{
  // setTimeout(()=>{
    resolve("成功")
    //reject('失败')
  // },2000)
  
})
promise.then(value=>{
  console.log("1",value) //1 成功
  return 100;
},reason=>{
  console.log("2",reason)
  return 200
}).then(value=>{
  console.log("then2", value) //then2 100
},reason=>{
  console.log("then2", reason)
})

2 promise对象子返回循环报错

//7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
  then(onFulfilled, onRejected){
    // 10. 实现then方法链式调用(写一个函数方法专门判断回调的结果是普通值还是promise,then方法返回的仍然是一个promise)
    let promise2 = new MyPromise((resolve,reject)=>{
      // 8.处理异步逻辑(pending状态下在then中将回调存起来)
      if(this.status === FULFILLED){
        //判断x是普通函数还是promise函数
        //如果普通函数直接调用resolve
        //如果是promise对象,查看promise的返回结果,在根据结果调用对应的方法
        //* 为了解决获取promise2,所以加一个定时器
        setTimeout(()=>{
          let x = onFulfilled(this.value);
          resolvePromise(promise2, x,resolve,reject)
        })
        
      }else if(this.status === REJECTED){
        let x = onRejected(this.reason)
        reject(x)
      }else{
        this.fulfilledCallacks.push(()=>{
          let x = onFulfilled(this.value);
          resolve(x)
        })
        this.rejectedCallbacks.push(()=>{
          let x = onRejected(this.reason)
          reject(x)
        })
      }
    })
    return promise2
  }

//11 处理promise返回值各种类型情况(普通值,promise)
function resolvePromise(promise2, x, resolve, reject){
  if(promise2 == x){
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  }
  if(x instanceof MyPromise){
    //promise对象
    x.then(resolve, reject);
  }else{
    //普通值
    resolve(x)
  }
}

//promise对象子返回循环报错
let promise = new MyPromise((resolve,reject)=>{
  // setTimeout(()=>{
    resolve("成功")
    //reject('失败')
  // },2000)
})
let p1 = promise.then(value=>{
  console.log(value); //
  return p1;
})
p1.then(value=>{
  console.log(value) 
},reason=>{
  console.log(reason.message) //Chaining cycle detected for promise #<Promise>
})

then进一步封装

//4 定义常量(成功使用fulfilled 失败使用rejected 等待使用pending)
let PENDING = 'pending';
let FULFILLED = 'fulfilled';
let REJECTED = 'rejected';
//1 创建一个MyPromise类
class MyPromise{
  //初始化status 状态为pending
  status = PENDING;
  //6.MyPromise类中定义value和reason,用来储存执行器执行成功和失败的返回值
  value= null;
  reason = null;
  //9.实现then方法多次调用添加多个处理函数 初始化回调为数组依次执行
  fulfilledCallacks = []
  rejectedCallbacks = [];
  //2 通过构造函数constructor,在执行这个类的时候传递一个执行器并立即执行
  constructor(executor){
    try{
      executor(this.resolve, this.reject)
    }catch(e){
      this.reject(e);
    }
  }  
  //3 定义resolve和reject方法
  //5.完成resolve和reject函数的状态改变(需要判断状态是否可以改变)
  resolve=(value) =>{
    if(this.status !== PENDING) return;
    this.status = FULFILLED;
    console.log("resolve=>",value) //成功
    this.value = value;
    // 执行成功回调
    while(this.fulfilledCallacks.length){
      this.fulfilledCallacks.shift()()
    }
  }
  reject = (reason)=>{
    if(this.status !== PENDING) return;
    this.status = REJECTED;
    this.reason = reason;
    // 执行成功回调
    while(this.rejectedCallbacks.length){
      this.rejectedCallbacks.shift()()
    }
  }   
  //7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
  then(onFulfilled, onRejected){
    // 10. 实现then方法链式调用(写一个函数方法专门判断回调的结果是普通值还是promise,then方法返回的仍然是一个promise)
    let promise2 = new MyPromise((resolve,reject)=>{
      // 8.处理异步逻辑(pending状态下在then中将回调存起来)
      if(this.status === FULFILLED){
        //判断x是普通函数还是promise函数
        //如果普通函数直接调用resolve
        //如果是promise对象,查看promise的返回结果,在根据结果调用对应的方法
        //* 为了解决获取promise2,所以加一个定时器
        setTimeout(()=>{
          try{
            let x = onFulfilled(this.value);
            resolvePromise(promise2, x,resolve,reject)
          }catch(e){
            reject(e);
          }
        })
      }else if(this.status === REJECTED){
        setTimeout(()=>{
          try{
            let x = onRejected(this.reason);
            resolvePromise(promise2, x,resolve,reject);
          }catch(e){
            reject(e);
          }
        })
      }else{
        this.fulfilledCallacks.push(()=>{
          setTimeout(()=>{
            try{
              let x = onFulfilled(this.value);
              resolvePromise(promise2, x,resolve,reject)
            }catch(e){
              reject(e);
            }
          })
        })
        this.rejectedCallbacks.push(()=>{
          setTimeout(()=>{
            try{
              let x = onRejected(this.reason);
              resolvePromise(promise2, x,resolve,reject);
            }catch(e){
              reject(e);
            }
          })
        })
      }
    })
    return promise2
  }
}
//11 处理promise返回值各种类型情况(普通值,promise)
function resolvePromise(promise2, x, resolve, reject){
  if(promise2 == x){
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  }
  if(x instanceof MyPromise){
    //promise对象
    x.then(resolve, reject);
  }else{
    //普通值
    resolve(x)
  }
}

var promise = new MyPromise(function(resolve, reject) {
  setTimeout(() => {
    resolve('成功')
  },2000)
  // resolve('成功')
})
promise.then(value => {
  console.log(value)
  // throw new Error('then error')
  return 'aaa'
}, reason => {
  console.log(reason)
  return 1000
}).then(value => {
  console.log('value2')
  console.log(value)     
}, reason => {
  console.log('报错2')
  console.log(reason)
})

then参数可变的情况

then(onFulfilled, onRejected){
    onFulfilled= onFulfilled? onFulfilled: value =>this.value;
    onRejected= onRejected? onRejected: reason =>{throw this.reason};
}
//处理没有参数的情况
.then().then()

四Promise.all

static all(array){
    let result=[];
    let index=0;
    return new MyPromise((resolve,reject)=>{
      function addData(key,value){
        result[key]=value;
        index++;
        if(index==array.length){
          resolve(result)
        }
      }
      for(let i=0;i<array.length;i++){
        let current = array[i];
        if(current instanceof MyPromise){
          //promise对象
          current.then(value=>addData(i,value),reason=>reject(i,reason))
        }else{
          //普通值
          addData(i,array[i])
        }
      }
    })
  }

function p1() {
  return new Promise(function (resolve, reject) {
    setTimeout(function() {
      resolve('p1')
    },2000)
  })
}
function p2() {
  return new Promise(function (resolve, reject) {
    resolve('p2')
  })
}
MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(function(result) {
  // result -> ['a', 'b', 'p1', 'p2', 'c']
  console.log(result)
})

五Promise.resolve

//Promise.resolve
  static resolve(value){
    //参数为promise对象直接输出
    if(value instanceof MyPromise) return value;
    //参数为普通值,就创建promise方法
    return new MyPromise(resolve=>resolve(value))
  }

function p1() {
  return new MyPromise(function (resolve, reject) {
    resolve('hello')
  })
}
MyPromise.resolve(10).then(value => console.log(value))
MyPromise.resolve(p1()).then(value => console.log(value))

Promise.reject

//Promise.reject 返回rejected状态的promise
  static reject(value){
    return new MyPromise((undefined,reject)=>{
      reject(value)
    })
  }

六Promise.finally

//Promise.finally
  finally(callback){
    //通过then获取当前promise对象的状态
    return this.then(value=>{
      return MyPromise.resolve(callback()).then(()=>value);
    },reason=>{
      return MyPromise.resolve(callback()).then(()=>{throw reason});
    })
  }

七 Promise.catch

//Promise.prototype.catch
  catch(failCallback){
    return this.then(undefined,failCallback)
  }

整体代码

/**
 * 手写Promise
 * 1.创建MyPromise类
 * 2.通过构造函数constructor,在执行这个类的时候需要传递一个执行器进去并立即调用
 * 3.定义resolve和reject
 * 4.定义状态常量(成功fulfilled失败rejected等待pending),初始化为pending
 * 5.完成resolve和reject函数的状态改变(需要判断状态是否可以改变)
 * 6.MyPromise类中定义value和reason,用来储存执行器执行成功和失败的返回值
 * 7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
 * 8.处理异步逻辑(pending状态下在then中将回调存起来)
 * 9.实现then方法多次调用添加多个处理函数 初始化回调为数组依次执行
 * 10.实现then方法链式调用(写一个函数方法专门判断回调的结果是普通值还是promise,then方法返回的仍然是一个promise
 * 11处理promise返回值各种类型情况
 * 12then方法链式调用识别Promise对象返回
 * 13promise实现捕获错误及then链式调用其他状态代码补充
 * 14将then方法的参数变为可选参数
 * 15 Promise.all
 * 16 Promise.resolve返回promise
 * 17 finally方法 不管成功失败都会执行一次
 * 18 catch方法实现
 * 19 reject方法实现
 * 20 race方法实现
 */

//4 定义常量(成功使用fulfilled 失败使用rejected 等待使用pending)
let PENDING = 'pending';
let FULFILLED = 'fulfilled';
let REJECTED = 'rejected';
//1 创建一个MyPromise类
class MyPromise{
  //初始化status 状态为pending
  status = PENDING;
  //6.MyPromise类中定义value和reason,用来储存执行器执行成功和失败的返回值
  value= null;
  reason = null;
  //9.实现then方法多次调用添加多个处理函数 初始化回调为数组依次执行
  fulfilledCallacks = []
  rejectedCallbacks = [];
  //2 通过构造函数constructor,在执行这个类的时候传递一个执行器并立即执行
  constructor(executor){
    try{
      executor(this.resolve, this.reject)
    }catch(e){
      this.reject(e);
    }
  }  
  //3 定义resolve和reject方法
  //5.完成resolve和reject函数的状态改变(需要判断状态是否可以改变)
  resolve=(value) =>{
    if(this.status !== PENDING) return;
    this.status = FULFILLED;
    console.log("resolve=>",value) //成功
    this.value = value;
    // 执行成功回调
    while(this.fulfilledCallacks.length){
      this.fulfilledCallacks.shift()()
    }
  }
  reject = (reason)=>{
    if(this.status !== PENDING) return;
    this.status = REJECTED;
    this.reason = reason;
    // 执行成功回调
    while(this.rejectedCallbacks.length){
      this.rejectedCallbacks.shift()()
    }
  }   
  //7.MyPromise类中添加then方法,成功回调有一个参数 表示成功之后的值,失败回调一个参数 表示失败的原因
  then(onFulfilled, onRejected){
    onFulfilled= onFulfilled? onFulfilled: value =>this.value;
    onRejected= onRejected? onRejected: reason =>{throw this.reason};
    // 10. 实现then方法链式调用(写一个函数方法专门判断回调的结果是普通值还是promise,then方法返回的仍然是一个promise)
    let promise2 = new MyPromise((resolve,reject)=>{
      // 8.处理异步逻辑(pending状态下在then中将回调存起来)
      if(this.status === FULFILLED){
        //判断x是普通函数还是promise函数
        //如果普通函数直接调用resolve
        //如果是promise对象,查看promise的返回结果,在根据结果调用对应的方法
        //* 为了解决获取promise2,所以加一个定时器
        setTimeout(()=>{
          try{
            let x = onFulfilled(this.value);
            resolvePromise(promise2, x,resolve,reject)
          }catch(e){
            reject(e);
          }
        })
      }else if(this.status === REJECTED){
        setTimeout(()=>{
          try{
            let x = onRejected(this.reason);
            resolvePromise(promise2, x,resolve,reject);
          }catch(e){
            reject(e);
          }
        })
      }else{
        this.fulfilledCallacks.push(()=>{
          setTimeout(()=>{
            try{
              let x = onFulfilled(this.value);
              resolvePromise(promise2, x,resolve,reject)
            }catch(e){
              reject(e);
            }
          })
        })
        this.rejectedCallbacks.push(()=>{
          setTimeout(()=>{
            try{
              let x = onRejected(this.reason);
              resolvePromise(promise2, x,resolve,reject);
            }catch(e){
              reject(e);
            }
          })
        })
      }
    })
    return promise2
  }

  //Promise.prototype.finally
  finally(callback){
    //通过then获取当前promise对象的状态
    return this.then(value=>{
      return MyPromise.resolve(callback()).then(()=>value);
    },reason=>{
      return MyPromise.resolve(callback()).then(()=>{throw reason});
    })
  }
  //Promise.prototype.catch
  catch(failCallback){
    return this.then(undefined,failCallback)
  }
  //Promise.all
  static all(array){
    let result=[];
    let index=0;
    return new MyPromise((resolve,reject)=>{
      function addData(key,value){
        result[key] = value;
        index++;
        if(index===array.length){
          resolve(result);
        }
      }
      for(let i=0;i<array.length;i++){
        let current = array[i];
        if(current instanceof MyPromise){
          //promise对象
          current.then(value=>addData(i,value),reason=>addData(i,reason))
        }else{
          //普通值
          addData(i,array[i])
        }
      }
    })
  }
  //Promise.race 
  static race(promises){
    return new MyPromise((resolve,reject)=>{
      //判断是不是数组
      if(!Array.isArray(promises)){
        return reject(new TypeError('Argument is not iterable'));
      }
      //等待第一个被敲定
      promises.forEach(p=>{
        MyPromise.resolve(p).then(res=>{resolve(res)},err=>{reject(err)})
      })
    })
  }
  //Promise.resolve
  static resolve(value){
    //参数为promise对象直接输出
    if(value instanceof MyPromise) return value;
    //参数为普通值,就创建promise方法
    return new MyPromise(resolve=>resolve(value))
  }
  //Promise.reject 返回rejected状态的promise
  static reject(value){
    return new MyPromise((undefined,reject)=>{
      reject(value)
    })
  }
}
//11 处理promise返回值各种类型情况(普通值,promise)
function resolvePromise(promise2, x, resolve, reject){
  if(promise2 == x){
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
  }
  if(x instanceof MyPromise){
    //promise对象
    x.then(resolve, reject);
  }else{
    //普通值
    resolve(x)
  }
}


const p1 = new MyPromise((resolve,reject)=>{
  setTimeout(()=>{
    resolve(1)
  },2000)
})
const p2 = new MyPromise((resolve,reject)=>{
  setTimeout(()=>{
    reject(2)
  },1000)
})
MyPromise.race([p1,p2]).then(res=>{
  console.log("res",res);
},err=>{
  console.log('err',err)
})

 

posted on 2019-01-18 16:42  执候  阅读(115)  评论(0编辑  收藏  举报