Promise.all和Promise.race的使用及利用Promise实现compose函数

671 阅读2分钟

1.Promise.all的使用

    1. 方法接收的参数为promise的iterable类型并且返回一个promise
    1. 输入的所有promise的resolve回调的结果是一个数组
    1. 所有输入的promise的resolve回调都结束了或者iterable中没有promise了时则执行回调
    1. 只要任何一个输入的promise的reject回调执行或者输入不合法的错误就会立即抛出错误,并且reject的是第一个抛出的错误信息
let p1 = new Promise((resolve, reject) => {setTimeout(() => resolve(1), 1000)})
let p2 = Promise.resolve(2)
let p3 = 3
// [1, 2, 3]
Promise.all([p1, p2, p3]).then(res => console.log(res))

// 存在reject回调的情况
let p1 = new Promise((resolve, reject) => {setTimeout(() => resolve(1), 1000)})
let p2 = Promise.reject(2)
let p3 = 3
// 2
Promise.all([p1, p2, p3]).then(res => console.log(res), err => console.log(err))

知道了Promise.all的实现原理那么便可以手写一个其实现方法,源码如下所示

Promise.prototype._all = function (promises) {
  // 返回一个promise
  return new Promise((resolve, reject) => {
    // 传入的为一个可迭代对象
    if(!Array.isArray(promises)) {
      throw new TypeError('promises is not iterable')
    } 
    // result用于存储每个promise的结果, count用于统计已获取到值得promise
    let result = [], count = 0
    promises.forEach((promise, index) => {
      promise.then(res => {
        result[index] = res
        count++
        count === promises.length && resolve(result)
      }, err => reject(err))
    })
  })
}

2.Promise.race的使用

    1. 参数: 可迭代对象
    1. 返回值: 一个Promise只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空) Promise.race的使用
let p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(1)}, 2000)})
let p2 = new Promise((resolve, reject) => {setTimeout(() => {resolve(2)}, 1000)})
Promise.race([p1, p2]).then(res => console.log(res), err => console.log(err))

了解了Promise.race的使用的使用过程之后可以来实现一下Promise.race

Promise.prototype._race = function (promises) {
  return new Promise((resolve, reject) => {
    if(!Array.isArray(promises)) {
      throw new TypeError('promises is not iterable')
    } 
    // issue用于判断是否已经有promise执行完毕
    let issue = true
    promises.forEach(promise => {
      promise.then(res => {
        if(issue) {
          issue = false
          resolve(res)
        }
      }, err => reject(err))
    })
  })
}

3.promise实现compose函数

首先什么叫compose函数呢?1.后一个函数的返回值作为前一个函数的参数2.最后一个函数可以接受单个参数,前面的函数只能够接受单个参数 eg: a(b(c(d('XXX')))) const func = compose(a, b, c, d) func('XXX')

    1. 实现方案1
function add1(x) {
  console.log("===>add1");
  return x + 1
}
function add2(x) {
  console.log("===>add2");
  return x + 2
}
function add3(x) {
  console.log("===>add3");
  return x + 3
}
const add4 = (...args) => args.reduce((pre, cur) => pre + cur)
function compose(...fns) {
  let length = fns.length
  let count = length - 1
  let result
  return function fun(...arg) {
    result = fns[count].apply(this, arg) 
    if(count <= 0) {
      count = length - 1
      return result
    }
    count--
    return fun.call(null, result)
  }
}
let func = compose(add1, add2, add3, add4)
// 16
console.log(func(1, 2, 3, 4));
    1. 实现方案2
function compose(...fns) {
  return x => fns.reduce((promise, fn) => promise.then(fn), Promise.resolve(x)) 
}
let func = compose(add3, add2, add1)
// 10
func(4).then(res => console.log(res))
    1. 实现方案3
async function compose(...fns) {
  return async x => {
    for(const fn of fns) {
      x = await fn(x)
    }
    return x
  }
}
let func = compose(add3, add2, add1)
// 10:第一个res是一个异步函数即compose函数的返回值
func.then(res => res(4)).then(res => console.log(res))