当前位置: 首页 > news >正文

链式触发器

某些需求接口是并发处理,多个接口一并触发,这种一般通过 Promise.all 处理,但是有时候需要链式触发,也就是后一个根据前一个结果处理

所以就有了下面这个代码

/**
 * 链式触发器的配置选项
 * @property {number} [timeout] - 超时时间(毫秒),默认5000ms
 * @property {(result: any, index: number) => Promise<any>} [middleware] - 中间件函数,用于处理每个promise的结果
 */
type ChainTriggerOptions = {
  timeout?: number;
  middleware?: (result: any, index: number) => Promise<any>;
};

/**
 * 链式触发器 - 顺序执行一组异步函数,支持中间件处理和超时控制
 * @template T - 异步函数数组类型
 * @param {T} promises - 要顺序执行的异步函数数组
 * @param {ChainTriggerOptions} [options] - 配置选项
 * @returns {Promise<Array<Awaited<ReturnType<T[number]>>>>} - 返回所有异步函数结果的数组
 * @example
 * // 基本用法
 * chainTrigger([
 *   () => fetch('/api/data1'),
 *   () => fetch('/api/data2'),
 *   () => fetch('/api/data3')
 * ]).then(results => {
 *   console.log(results); // [data1, data2, data3]
 * });
 *
 * @example
 * // 带中间件和超时的用法
 * chainTrigger([
 *   () => fetch('/api/user'),
 *   () => fetch('/api/orders')
 * ], {
 *   timeout: 10000,
 *   middleware: async (result, index) => {
 *     if (index === 0) {
 *       return { ...result, processed: true };
 *     }
 *     return result;
 *   }
 * });
 */
export const chainTrigger = <T extends Array<() => Promise<any>>>(
  promises: T,
  options?: ChainTriggerOptions
): Promise<Array<Awaited<ReturnType<T[number]>>>> => {
  const { timeout = 5000, middleware } = options || {};

  return new Promise((resolve, reject) => {
    const results: any[] = [];
    let currentIndex = 0;
    let isTimedOut = false;

    const timer =
      timeout > 0
        ? setTimeout(() => {
            isTimedOut = true;
            reject(new Error(`Chain trigger timed out after ${timeout}ms`));
          }, timeout)
        : null;

    const executeNext = async () => {
      if (currentIndex >= promises.length || isTimedOut) {
        timer && clearTimeout(timer);
        resolve(results as Array<Awaited<ReturnType<T[number]>>>);
        return;
      }

      try {
        const promise = promises[currentIndex];
        let result = await promise();

        if (middleware) {
          result = await middleware(result, currentIndex);
        }

        results.push(result);
        currentIndex++;
        executeNext();
      } catch (error) {
        timer && clearTimeout(timer);
        reject(error);
      }
    };

    executeNext();
  });
};

可以根据示例直接使用,简洁简单

相关文章:

  • 如何使用Tomcat
  • Day 9
  • Node 处理 request 的过程中,都会更新哪些 metadata 和 property
  • 餐饮厨房开源监控安全系统的智能革命
  • 小刚说C语言刷题——第20讲 循环之嵌套循环
  • 【面经】兼顾频繁插入/删除和查询访问 非阻塞网络I/O模型 connect的阻塞性 `unique_ptr`的使用场景和析构机制
  • 20年AB1解码java
  • 【PyTorch项目实战】卷积(Convolution ) + 反卷积(Deconvolution)
  • 文章记单词 | 第27篇(六级)
  • WePY 框架:小程序开发的“Vue式”利器!!!
  • gogs私服对应SSH 协议配置
  • 基于 OpenHarmony 5.0 的星闪轻量型设备应用开发——Ch3 设备驱动开发
  • python基础:位置互换
  • 【前端】【React】useCallback的作用与使用场景总结
  • 银行业务知识序言
  • 基于labview的多功能数据采集系统
  • 已经安装了pip,出现pip command not found【解决方法】
  • 如何用VBA编辑器合并Word文档:详细教程
  • spark-rdd
  • 【补题】P9423 [蓝桥杯 2023 国 B] 数三角