动手实现Promise.map

ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(要想成功,你必须自我制造机会,绝不能愚蠢地坐在路边,等待有人经过,邀请你同往财富与幸福之路。——歌夫)
ㅤㅤㅤ
ㅤㅤㅤ
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

前言

在使用nodejs开发后端业务过程中,我们难免要对异步IO流进行控制,以免内存,CPU,流量等突发导致数据库告警异常。
我们常用的异步流程控制库有bluebirdasync
但我们有时只需要使用’map’api来限制并发却引入一个庞大的npm包,这显然是得不偿失的,所以我们在这里手动实现一个promise.map

源码
  /**
   * promise.map 并行限流控制
   * @param iterable 需要处理的数组
   * @param mapper 执行的回调函数
   * @param options 其他配置 concurrency 并发数,用于控制同时执行数
   * @returns 返回值列表
   */
  public static async promiseMap(iterable, mapper, options) {
    options = options || {};
    // 默认并发为1
    let concurrency = options.concurrency || 1;
    // 当前循环下标
    let index = 0;
    // 处理结果列表
    const results = [];
    // 数组迭代器 通过.next取值 如果.next.done为真 则取值完毕
    const iterator = iterable[Symbol.iterator]();
    // promise列表
    const promises = [];
    // 具体执行函数
    const wrappedMapper = ()=> {
      // 取下一个值
      const next = iterator.next();
      // 不存在则返回
      if (next.done) return null;
      // 每次记录下标,用于回调函数使用
      const i = index++;
      // 执行回调函数
      const mapped = mapper(next.value, i);
      // 执行promise
      return Promise.resolve(mapped).then(resolved => {
        // 处理结果赋值
        results[i] = resolved;
        // 继续递归调用
        return wrappedMapper();
      })
    };
    /**
     * 通过循环并发数来限流并行任务
     * 每一个并发都会生成一个promise执行链条,每一个promise链条会反复递归取值调用
     * 比如并发是2 则生成两个promise链条放入promise.all中执行。每一个链条都会持续取值执行
     */
    while (concurrency-- > 0) {
      // 获取promise执行链
      const promise = wrappedMapper();
      // 存在则放入primise列表
      if (promise) promises.push(promise);
      else break;
    }
    // 并行执行promise链条
    await Promise.all(promises);
    // 返回结果
    return results;
  }
使用示例
await promiseMap([], (v) => // .... code, { concurrency: 1 });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值