Promise

72 阅读3分钟

1 Promise 基础概念

1.1 了解 Promise

  • Promise 是什么?
**Promise** 实际上就是一个对象 用来去表示一个异步任务最终结束过后究竟是成功 还是失败  
  • promise 为了解决什么?

    • Promise 处理异步调用最大的优势就是 :链式调用 解决回调过深的问题
    为了解决回调地狱问题 **CommonJS** 社区提出了**Promise**的规范 后来 **ES2015** 中被标准化称为**语言规范**
    - 地狱回调怎么产生的?
        直接使用传统回调方式去完成复杂的异步流程,就无法避免大量的回调函数嵌套 就会产生回调地狱问题
    
  • Promise 任务结束后的 padding

padding (padding状态就像是内部对外部做出了一个承诺 在这个时候是待定的状态 有可能成功 也有可能失败 )
padding 之后 不管成功还是失败 都会有一个结果返回 返回了相应的结果之后 当前任务就结束了 不管怎么样 都不会再有反应

2 Promise 常见用法 及 异常处理 等...

常见用法

  • 错误用法:promise 需要连续请求多次
  ajax('./xxx.json').then(function(res){  
      ajax(res.url).then(function(res){  
        ajax(res,url).then(function(){  
            ......
        })  
      })  
  })
  • 正确用法:借助 Promise .then 方法链式调用的特点 尽量的去保证异步任务的扁平化 链式调用
 // Promise 对象的 then 方法会返回一个全新的 Promise 对象 所以说我们才可以使用链式调用的方式去添加 then 方法 
 ajax('../api.json').then((res)=>{  
    console.log(111);  
 }).then((res)=>{  
 // 后面的 then 方法就是在为上一个 then 返回的 Promise 注册对应的回调
    console.log(222); 
    return ajax('../api.json')  
 }).then((res)=>{  
 // 前面 then 方法中的回调函数的返回值会作为后面 then 方法回调的参数
    console.log(333);  
    console.log(res); 
    return 'foo' 
 }).then((res)=>{  
 // 如果回调中返回的是 Promise 那后面 then 方法的回调会等待它的结束
    console.log(res); 
 })
 
  • Promise 异常处理
Promise.catch() === .then(undefined,()=>{})
  • Promise 静态方法
 Promise.resolve('foo').then(res=>{}) === new Promise((resolve,reject)=>{ resolve('foo')})
  • Promise 并行执行

    • Promise.all()
    Promise.all()  这个方法会返回一个全新的 Promise 对象   
    当内部所有的 Promise 都完成以后  返回全新的 Promise 就会执行   
    如果说 Promise.all()  中有任何一个promise失败了 那么这个 promise 就会以失败结束
    使用方法:  
         Promise.all([  
            ajax('../xxx'),  
            ajax('../xxx')  
         ])
    
    • Promise.race()
    Promise.race()  这个方法只会等待第一个结束的任务
    使用方法:
        Promise.race([
          request,
          timeout
        ]).then(res=>{
          console.log(res);
        }).catch(err=>{
          console.log(err);
        }) 
    

3 Promise 实现原理

  • Promise 最基础核心逻辑及实现
1. Promise 就是一个类,在执行这个类的时候 需要传递一个执行器进去 执行器会立即执行
2. Promise 中有三种状态 分别为
    padding 等待  
    fulfilled 成功  
    rejected 失败
    其中 padding 要不就 成功  padding -> fulfilled  
                要不就是失败 padding -> rejected  
                一旦状态确定 就不可改变
                
                
 3. resolve 和rejected 函数是用来更改状态的   
     resolve : fulfilled  
     rejected:  rejected
 
4. then方法内部做的事情就是判断状态 ,如果状态是成功 调用成功的回调函数,如果状态是失败 
 调用失败的回调   then 方法是定义在原型对象上的
 
5. then 成功回调有一个参数 表示成功之后的值 then 失败回调有一个参数 表示失败后的值

const PADDING = 'padding';
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class Mypromise {
  // constructor 是构造函数上的方法 需要传入一个 执行器 让它立即执行
  constructor(executed) {
    executed(this.resolve, this.reject)
  }

  // 先定义一个初始状态
  state = PADDING;
  value = undefined;
  reason = undefined;

  // 成功的
  resolve = value => {
    if (this.state !== PADDING) return
    // 更改状态
    this.state = FULFILLED
    // 保存成功的值
    this.value = value
  }

  // 失败的
  reject = reason => {
    if (this.state !== PADDING) return
    // 更改状态
    this.state = REJECTED
    // 保存失败原因
    this.reason = reason
  }

  // 判断状态
  then = (succeedCallback, failCallback) => {
    if (this.state === FULFILLED) {
      succeedCallback(this.value)
    } else if (this.state === REJECTED) {
      failCallback(this.reason)
    }
  }
}
export default Mypromise