【JS】Promise学习总结

1.Promise简介

参考:https://blog.csdn.net/weixin_44972008/article/details/113779708

1.1 Promise是什么

  • 抽象表达:Promise是JS中进行异步编程的新的解决方案(旧方案是单纯使用回调函数)
  • 具体表达:
    ①从语法上看:Promise是一个构造函数 (自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法)
    ②从功能上看:promise对象用来封装一个异步操作并可以获取其成功/失败的结果值
  • 阮一峰的解释:
    所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
    从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
    Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理

Promise 的状态:
实例对象promise中的一个属性 PromiseState
pending 变为 resolved/fullfilled
pending 变为 rejected
注意:
对象的状态不受外界影响
只有这两种,且一个 promise 对象只能改变一次
一旦状态改变,就不会再变,任何时候都可以得到这个结果
无论成功还是失败,都会有一个结果数据。成功的结果数据一般称为 value,而失败的一般称为 reason。

1.2 Promise基本使用

流程:
在这里插入图片描述

基本使用:

const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(reason);
  }
});

1.3 为什么使用Promise

  • 指定回调函数的方式更加灵活
    旧的:必须在启动异步任务前指定

  • 支持链式调用,可以解决回调地狱问题
    回到地狱:回调函数嵌套调用,外部回调函数异步执行的结果是其内部嵌套的回调函数执行的条件
    回调函数缺点:不便于阅读、不便于异常处理
    解决回调地狱的方案:

  • Promise链式调用

  • async/await

1.4 中断Promise链

我们都知道promise状态一旦变为resolve或reject就不会再改变,中间无法中断,那如何中断链式调用呢?
当使用 promise 的 then 链式调用时,在中间中断,不再调用后面的回调函数
办法:在回调函数中返回一个 pending 状态的 promise 对象

new Promise((resolve, reject) => {
   //resolve(1)
   reject(1)
}).then(
  value => {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value => {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value => {
    console.log('onResolved3()', value)
  }
).catch(
  reason => {
    console.log('onRejected1()', reason)
  }
).then(
  value => {
    console.log('onResolved4()', value)
  },
  reason => {
    console.log('onRejected2()', reason)
  }
)
// onRejected1() 1
// onResolved4() undefined

为了在 catch 中就中断执行,可以这样写:

new Promise((resolve, reject) => {
   //resolve(1)
   reject(1)
}).then(
  value => {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value => {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value => {
    console.log('onResolved3()', value)
  }
).catch(
  reason => {
    console.log('onRejected1()', reason)
    return new Promise(() => {}) // 返回一个pending的promise
  }
).then(
  value => {
    console.log('onResolved4()', value)
  },
  reason => {
    console.log('onRejected2()', reason)
  }
)
// onRejected1() 1

在 catch 中返回一个新的 promise,且这个 promise 没有结果。
由于,返回的新的 promise 结果决定了后面 then 中的结果,所以后面的 then 中也没有结果。
这就实现了中断 promise链的效果。

2.Promise顺序请求

方法1——连续使用then链式调用
方法2——使用promise构建队列
方法3——使用async、await实现类似同步编程,async函数内部实现同步
参考:https://www.jianshu.com/p/dbda3053da20

方法1:链式调用

function getA(){
    return  new Promise(function(resolve, reject){ 
    setTimeout(function(){     
          resolve(2);
      }, 1000);
  });
}
 
function getB(){
    return  new Promise(function(resolve, reject){       
        setTimeout(function(){
            resolve(3);
        }, 1000);
    });
}
 
function addAB(a,b){
    return a+b
}

function getResult(){
    var  obj={};
    Promise.resolve().then(function(){
        return  getA() 
    })
    .then(function(a){
         obj.a=a;
    })
    .then(function(){
        return getB() 
    })
    .then(function(b){
         obj.b=b;
         return obj;
    })
    .then(function(obj){
       return  addAB(obj['a'],obj['b'])
    })
    .then(data=>{
        console.log(data)
    })
    .catch(e => console.log(e));
}
getResult();

3.Promise并行请求

getA和getB并行执行,然后输出结果。如果有一个错误,就抛出错误
每一个promise都必须返回resolve结果才正确
每一个promise都不处理错误
参考:https://www.jianshu.com/p/dbda3053da20

/**
 * 每一个promise都必须返回resolve结果才正确
 * 每一个promise都不处理错误
 */

const getA = new Promise((resolve, reject) => {
   //模拟异步任务
   setTimeout(function(){
     resolve(2);
   }, 1000) 
})
.then(result => result)


const getB = new Promise((resolve, reject) => {
   setTimeout(function(){
     // resolve(3);
     reject('Error in getB');
   }, 1000) 
})
.then(result => result)


Promise.all([getA, getB]).then(data=>{
    console.log(data)
})
.catch(e => console.log(e));

getA和getB并行执行,然后输出结果。总是返回resolve结果
每一个promise自己处理错误

/**
 * 每一个promise自己处理错误
 */

const getA = new Promise((resolve, reject) => {
   //模拟异步任务
   setTimeout(function(){
     resolve(2);
   }, 1000) 
})
.then(result => result)
.catch(e=>{

})


const getB = new Promise((resolve, reject) => {
   setTimeout(function(){
     // resolve(3);
     reject('Error in getB');
   }, 1000) 
})
.then(result => result)
.catch(e=>e)


Promise.all([getA, getB]).then(data=>{
    console.log(data)
})
.catch(e => console.log(e));

Promise.all传入同一个方法不同参数的封装
应用场景 比如你需要同时发起多页请求,需要传入页码但是方法都是一样的此时我们就可以进行封装一下,很实用的一个技巧
参考:https://blog.csdn.net/qq_25842063/article/details/84284911

/*
* @params : func:你封装的方法 params: 参数的数组
*/
let getDataBind = (func, params) => {
        return params.map( item => {
            return func.call(null, item) //传参
        })
    }
 /*
 @params : page_no 页码  
 getData 可以换成你自己需要重复操作的方法,同理
 */
let getData = (page_no) => {
        let saveListData = JSON.parse(localStorage.getItem(this.props.saveListData));
        let params = {
            page_no:page_no,
            ...saveListData.loadParams
        }
        return new Promise(resolve => {
            get(this.props.sortUrl, params, this, false).then(function (data) {
                resolve(data.result;);
            });
        })
    }  
 Promise.all(this.getDataBind(this.getData, arrPage))
	.then( resultArr  => {
		    resultArr = resultArr.flat();//拉平数组
		    console.log(resultArr)    //这里就获取到所有页的数据了
	});
//

4. Promise 核心源码

手写核心源码: https://blog.csdn.net/weixin_44972008/article/details/114134995

参考:https://www.jianshu.com/p/43de678e918a

4.1 整体框架:

/**
 * 自定义Promise函数模块:IIFE
 */
(function (window) {
  const PENDING = 'pending'
  const RESOLVED = 'fulfilled'
  const REJECTED = 'rejected'

  /**
   * Promise构造函数
   * @param {function} executor 执行器函数(同步执行)(resolve, reject) => {}
   */
  function Promise(executor) {
  
  }

  /**
   * Promise原型对象then方法 
   * 指定成功和失败的回调函数
   * @param {function} onResolved 成功的回调函数(value) => {}
   * @param {function} onRejected 失败的回调函数(reason) => {}
   * @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
   */
  Promise.prototype.then = function (onResolved, onRejected) {
    
  }

  /**
   * Promise原型对象catch方法
   * 指定失败的回调函数
   * @param {function} onRejected 失败的回调函数(reason) => {}
   * @returns 一个新的promise对象
   */
  Promise.prototype.catch = function (onRejected) {
    
  }

  /**
   * Promise函数对象resolve方法
   * @param {*} value 成功的值
   * @returns 一个成功/失败的promise
   */
   Promise.resolve = function (value) {

  }

  /**
   * Promise函数对象reject方法
   * @param {*} resaon 失败的原因
   * @returns 一个失败的promise
   */
  Promise.reject = function (resaon) {

  }

  /**
   * Promise函数对象all方法
   * @param {Array<Promise>} promises 
   * @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
   */
  Promise.all = function (promises) {

  }

  /**
   *Promise函数对象race方法
   * @param {Array<Promise>} promises 
   * @returns 返回 一个promise,其结果由第一个完成的promise决定
   */
  Promise.race = function (promises) {

  }


  // 向外暴露Promise函数
  window.Promise = Promise
})(window)

4.1.1 Promise(executor)

Promise构造函数
executor: 执行器函数(同步执行)

/**
 * Promise构造函数
 * @param {*} executor 执行器函数(同步执行)(resolve, reject) => {}
 */
function Promise(executor) {

  const self = this; // 保存当前实例对象的this的值
  // 添加属性
  self.PromiseState = PENDING // 给promise对象指定status属性,初始值为pending
  self.PromiseResult = null // 给promise对象指定一个用于存储结果数据的属性
  self.callbacks = [] // 存的是对象 每个元素的结构:{onResolved() {}, onRejected() {}}

  /**
   * executor内部定义成功时调用的函数
   * @param {*} value 成功的值
   * @returns 
   */
  function resolve(value) {
    // 如果当前状态不是pending,直接结束
    if (self.PromiseState !== PENDING) return
    // 1. 修改对象的状态(promiseState)为 fulfilled
    self.PromiseState = RESOLVED 
    // 2. 设置对象结果值(promiseResult)为 value
    self.PromiseResult = value
    // 如果有待执行的callback函数,立即【异步】执行回调函数onResolved
    if (self.callbacks.length > 0) {
      setTimeout(() => { // 放入队列中执行所有成功的回调
        self.callbacks.forEach(callbacksObj => {
          callbacksObj.onResolved(value)
        })
      }, 0)
    }
  }
  
  /**
   * executor内部定义失败时调用的函数
   * @param {*} reason 失败的原因
   * @returns 
   */
  function reject(reason) {
    // 如果当前状态不是pending,直接结束
    if (self.PromiseState !== PENDING) return
    // 1. 修改对象的状态(promiseState)为 rejected
    self.PromiseState = REJECTED
    // 2. 设置对象结果值(promiseResult)为 reason
    self.PromiseResult = reason
    // 如果有待执行的callback函数,立即【异步】执行回调函数onRejected
    if (self.callbacks.length > 0) {
      setTimeout(() => { // 放入队列中执行所有失败的回调
        self.callbacks.forEach(callbacksObj => {
          callbacksObj.onRejected(reason)
        })
      }, 0)
    }
  }
  
  // 立即【同步】执行executor函数
  try {
    executor(resolve, reject)
  } catch(error) { // 如果执行器抛出异常,promise对象变成rejected状态
    reject(error)
  }
}

4.1.2 Promise.prototype.then

Promise.prototype.then = function (onResolved, onRejected) {
  const self = this
  return new Promise((resolve, reject) => {
    if (self.PromiseState === PENDING) { // 假如当前状态还是pending状态,将回调函数保存起来
      self.callbacks.push({
        onResolved(value) {
          // onResolved(self.PromiseResult)
          try {
            const result = onResolved(self.PromiseResult) // 执行成功的回调 result接收返回值
            if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
              // result.then(
              //   value => {
              //     resolve(value) // 当result成功时,让return的promise也成功
              //   },
              //   reason => {
              //     reject(reason) // 当result失败时,让return的promise也失败
              //   }
              // )
              result.then(resolve, reject) // 简洁写法
            } else { // 2. 如果回调函数返回的不是promise
              resolve(result)
            }
          } catch (error) { //1. 如果抛出异常
            reject(error)
          }
         },
        onRejected(reason) {
          // onRejected(self.PromiseResult)
          try {
            const result = onRejected(self.PromiseResult) // 执行失败的回调 result接收返回值
            if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
              result.then(resolve, reject)
            } else { // 2. 如果回调函数返回的不是promise
              resolve(result)
            }
          } catch (error) { //1. 如果抛出异常
            reject(error)
          }
         }
      })
    } else if (self.PromiseState === RESOLVED) { // resolved
      setTimeout(() => {
        /**
         * 1. 如果抛出异常,return的promise就会失败,reason是error
         * 2. 如果回调函数返回的不是promise,return的promise就会成功,value就是返回的值
         * 3. 如果回调函数返回的是promise,return的promise结果就是这个promise的结果
         */
        try {
          const result = onResolved(self.PromiseResult) // 执行成功的回调 result接收返回值
          if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
            // result.then(
            //   value => {
            //     resolve(value) // 当result成功时,让return的promise也成功
            //   },
            //   reason => {
            //     reject(reason) // 当result失败时,让return的promise也失败
            //   }
            // )
            result.then(resolve, reject) // 简洁写法
          } else { // 2. 如果回调函数返回的不是promise
            resolve(result)
          }
        } catch (error) { //1. 如果抛出异常
          reject(error)
        }
      }, 0)
    } else { // rejected
      setTimeout(() => {
        try {
          const result = onRejected(self.PromiseResult) // 执行失败的回调 result接收返回值
          if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
            result.then(resolve, reject)
          } else { // 2. 如果回调函数返回的不是promise
            resolve(result)
          }
        } catch (error) { //1. 如果抛出异常
          reject(error)
        }
      }, 0)
    }
  })
}

简化封装一下

/**
 * Promise原型对象then方法 
 * 指定成功和失败的回调函数
 * @param {function} onResolved 成功的回调函数(value) => {}
 * @param {function} onRejected 失败的回调函数(reason) => {}
 * @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
 */
Promise.prototype.then = function (onResolved, onRejected) {
  // 指定默认的成功的回调onResolved (向后传递成功的value)
  onResolved = typeof onResolved === 'function' ? onResolved : value => value
  // 指定默认的失败的回调onRejected(向后传递失败的reason 实现错误/异常传透的关键点)
  onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

  const self = this

  return new Promise((resolve, reject) => {
    /**
     * 调用指定回调函数处理,根据执行的结果改变return的promise的状态
     * @param {function} callback 指定回调函数
     */
    function handle(callback) {
      try {
        const result = callback(self.PromiseResult) // result获取回调函数执行(return)的结果
        if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
          result.then(resolve, reject) // 简洁写法
        } else { // 2. 如果回调函数返回的不是promise
          resolve(result)
        }
      } catch (error) { //1. 如果抛出异常
        reject(error)
      }
    }

    if (self.PromiseState === PENDING) { // 1. 当前状态是pending状态,将回调函数保存起来
      self.callbacks.push({
        onResolved(value) { //执行成功的回调函数,改promise的状态
          handle(onResolved)
         },
        onRejected(reason) { //执行失败的回调函数,改promise的状态
          handle(onRejected)
         }
      })
    } else if (self.PromiseState === RESOLVED) { // 2. resolved,【异步】执行onResolved并改变return的promise的状态
      setTimeout(() => {
        handle(onResolved)
      }, 0)
    } else { // 3. rejected,【异步】执行onRejected并改变return的promise的状态
      setTimeout(() => {
        handle(onRejected)
      }, 0)
    }
  })
}

4.1.3 Promise.prototype.catch

/**
 * Promise原型对象catch方法
 * 指定失败的回调函数
 * @param {function} onRejected 失败的回调函数(reason) => {}
 * @returns 一个新的promise对象
 */
Promise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected)
}

4.1.4 Promise.resolve

/**
 * Promise函数对象resolve方法
 * @param {*} value 成功的值
 * @returns 一个成功/失败的promise
 */
Promise.resolve = function (value) {
  // 返回一个成功/失败的promise
  return new Promise((resolve, reject) => {
    if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
      value.then(resolve,reject)
    } else { // value不是promise => promise状态变为成功,数据是value
      resolve(value)
    }
  })
}

4.1.5 Promise.reject

/**
 * Promise函数对象reject方法
 * @param {*} resaon 失败的原因
 * @returns 一个失败的promise
 */
Promise.reject = function (reason) {
  // 返回一个失败的promise
  return new Promise((resolve, reject) => {
    reject(reason)
  })
}

4.1.6 Promise.all

/**
 * Promise函数对象all方法
 * @param {Array<Promise>} promises 
 * @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
 */
Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    let count = 0 // 声明计数变量
    // const values = []; // 保存每个成功promise结果的数组
    const values = new Array(promises.length) // 指定数组长度
    for (let i = 0; i < promises.length; i++){
      // promises[i].then(value => {
      Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
        // 得知对象状态是成功
        count++
        // 将当前promise对象成功的结果存入到数组中
        values[i] = value
        if (count === promises.length) { //每个promise对象都成功
          resolve(values) // 修改函数状态
        }
      }, reason => {
          reject(reason)
        })
    }
  })
}

4.1.7 Promise.race

/**
 *Promise函数对象race方法
 * @param {Array<Promise>} promises 
 * @returns 返回 一个promise,其结果由第一个完成的promise决定
 */
Promise.race = function (promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++){
      // promises[i].then(value => {
      Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
        // 修改返回对象的状态为 成功
        resolve(value)
      }, reason => {
        reject(reason)
      })
    }
  })
}

4.1.8 自定义函数对象方法Promise.resolveDelay&Promise.rejectDelay

/**
 * 自定义方法 延时返回一个成功/失败的promise
 * @param {*} value 成功的数据
 * @param {Number} timeout 延迟时间
 * @returns 一个成功/失败的promise
 */
Promise.resolveDelay = function (value, timeout) {
  // 延时返回一个成功/失败的promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
        value.then(resolve,reject)
      } else { // value不是promise => promise状态变为成功,数据是value
        resolve(value)
      }
    })
  }, timeout);
}

/**
 * 自定义方法 延时返回一个失败的promise
 * @param {*} reason 失败的原因
 * @param {*} timeout 延迟时间
 * @returns 一个失败的promise
 */
Promise.rejectDelay = function (reason, timeout) {
  // 延时返回一个失败的promise
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(reason)
    }, timeout)
  })
}

4.2 Class写法:

  /**
 * 自定义Promise函数模块:IIFE
 */
(function (window) {

  const PENDING = 'pending'
  const RESOLVED = 'fulfilled'
  const REJECTED = 'rejected'

  class Promise {
    /**
     * Promise构造函数
     * @param {function} executor 执行器函数(同步执行)(resolve, reject) => {}
     */
    constructor(executor) {

      const self = this; // 保存当前实例对象的this的值
      // 添加属性
      self.PromiseState = PENDING // 给promise对象指定status属性,初始值为pending
      self.PromiseResult = null // 给promise对象指定一个用于存储结果数据的属性
      self.callbacks = [] // 存的是对象 每个元素的结构:{onResolved() {}, onRejected() {}}

      /**
       * executor内部定义成功时调用的函数
       * @param {*} value 成功的值
       * @returns 
       */
      function resolve(value) {
        // 如果当前状态不是pending,直接结束
        if (self.PromiseState !== PENDING) return
        // 1. 修改对象的状态(promiseState)为 fulfilled
        self.PromiseState = RESOLVED
        // 2. 设置对象结果值(promiseResult)为 value
        self.PromiseResult = value
        // 如果有待执行的callback函数,立即【异步】执行回调函数onResolved
        if (self.callbacks.length > 0) {
          setTimeout(() => { // 放入队列中执行所有成功的回调
            self.callbacks.forEach(callbacksObj => {
              callbacksObj.onResolved(value)
            })
          }, 0)
        }
      }
    
      /**
       * executor内部定义失败时调用的函数
       * @param {*} reason 失败的原因
       * @returns 
       */
      function reject(reason) {
        // 如果当前状态不是pending,直接结束
        if (self.PromiseState !== PENDING) return
        // 1. 修改对象的状态(promiseState)为 rejected
        self.PromiseState = REJECTED
        // 2. 设置对象结果值(promiseResult)为 reason
        self.PromiseResult = reason
        // 如果有待执行的callback函数,立即【异步】执行回调函数onRejected
        if (self.callbacks.length > 0) {
          setTimeout(() => { // 放入队列中执行所有失败的回调
            self.callbacks.forEach(callbacksObj => {
              callbacksObj.onRejected(reason)
            })
          }, 0)
        }
      }
    
      // 立即【同步】执行executor函数
      try {
        executor(resolve, reject)
      } catch (error) { // 如果执行器抛出异常,promise对象变成rejected状态
        reject(error)
      }
    }

    /**
     * Promise原型对象then方法 
     * 指定成功和失败的回调函数
     * @param {function} onResolved 成功的回调函数(value) => {}
     * @param {function} onRejected 失败的回调函数(reason) => {}
     * @returns 一个新的promise对象结果由onResolved/onRejected执行的结果决定
     */
    then (onResolved, onRejected) {
      // 指定默认的成功的回调onResolved (向后传递成功的value)
      onResolved = typeof onResolved === 'function' ? onResolved : value => value
      // 指定默认的失败的回调onRejected(向后传递失败的reason 实现错误/异常传透的关键点)
      onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

      const self = this

      return new Promise((resolve, reject) => {
        /**
         * 调用指定回调函数处理,根据执行的结果改变return的promise的状态
         * @param {function} callback 指定回调函数
         */
        function handle(callback) {
          try {
            const result = callback(self.PromiseResult) // result获取回调函数执行(return)的结果
            if (result instanceof Promise) { // 3. 如果回调函数返回的是promise
              result.then(resolve, reject) // 简洁写法
            } else { // 2. 如果回调函数返回的不是promise
              resolve(result)
            }
          } catch (error) { //1. 如果抛出异常
            reject(error)
          }
        }

        if (self.PromiseState === PENDING) { // 1. 当前状态是pending状态,将回调函数保存起来
          self.callbacks.push({
            onResolved(value) { //执行成功的回调函数,改promise的状态
              handle(onResolved)
            },
            onRejected(reason) { //执行失败的回调函数,改promise的状态
              handle(onRejected)
            }
          })
        } else if (self.PromiseState === RESOLVED) { // 2. resolved,【异步】执行onResolved并改变return的promise的状态
          setTimeout(() => {
            handle(onResolved)
          }, 0)
        } else { // 3. rejected,【异步】执行onRejected并改变return的promise的状态
          setTimeout(() => {
            handle(onRejected)
          }, 0)
        }
      })
    }


    /**
     * Promise原型对象catch方法
     * 指定失败的回调函数
     * @param {function} onRejected 失败的回调函数(reason) => {}
     * @returns 一个新的promise对象
     */
    catch (onRejected) {
      return this.then(undefined, onRejected)
    }


    /**
     * Promise函数对象resolve方法
     * @param {*} value 成功的值
     * @returns 一个成功/失败的promise
     */
    static resolve(value) {
      // 返回一个成功/失败的promise
      return new Promise((resolve, reject) => {
        if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
          value.then(resolve,reject)
        } else { // value不是promise => promise状态变为成功,数据是value
          resolve(value)
        }
      })
    }


    /**
     * Promise函数对象reject方法
     * @param {*} resaon 失败的原因
     * @returns 一个失败的promise
     */
    static reject (reason) {
      // 返回一个失败的promise
      return new Promise((resolve, reject) => {
        reject(reason)
      })
    }

  
    /**
     * Promise函数对象all方法
     * @param {Array<Promise>} promises 
     * @returns 一个promise,只有当所有promise都成功时才成功,否则只要有一个失败就失败
     */
     static all (promises) {
      return new Promise((resolve, reject) => {
        let count = 0 // 声明计数变量
        // const values = []; // 保存每个成功promise结果的数组
        const values = new Array(promises.length) // 指定数组长度
        for (let i = 0; i < promises.length; i++){
          // promises[i].then(value => {
            Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
            // 得知对象状态是成功
            count++
            // 将当前promise对象成功的结果存入到数组中
            values[i] = value
            if (count === promises.length) { //每个promise对象都成功
              resolve(values) // 修改函数状态
            }
          }, reason => {
              reject(reason)
            })
        }
      })
    }


    /**
     *Promise函数对象race方法
    * @param {Array<Promise>} promises 
    * @returns 返回 一个promise,其结果由第一个完成的promise决定
    */
    static race (promises) {
      return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++){
          // promises[i].then(value => {
          Promise.resolve(promises[i]).then(value => { // 防止数组中有不是promise的元素
            // 修改返回对象的状态为 成功
            resolve(value)
          }, reason => {
            reject(reason)
          })
        }
      })
    }

    /**
     * 自定义方法 延时返回一个成功/失败的promise
     * @param {*} value 成功的数据
     * @param {Number} timeout 延迟时间
     * @returns 一个成功/失败的promise
     */
    static resolveDelay (value, timeout) {
      // 延时返回一个成功/失败的promise
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (value instanceof Promise) { // value是promise => 使用value的结果作为promise的结果
            value.then(resolve,reject)
          } else { // value不是promise => promise状态变为成功,数据是value
            resolve(value)
          }
        })
      }, timeout);
    }

    /**
     * 自定义方法 延时返回一个失败的promise
     * @param {*} reason 失败的原因
     * @param {*} timeout 延迟时间
     * @returns 一个失败的promise
     */
     static rejectDelay (reason, timeout) {
      // 延时返回一个失败的promise
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(reason)
        }, timeout)
      })
    }
  }

  // 向外暴露Promise函数
  window.Promise = Promise
})(window)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值