You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持同步/异步回调的通用failSafe函数?

通用兼容同步/异步的错误捕获函数实现思路

核心思路是利用async/await的特性,统一处理同步函数和异步函数的执行与错误捕获,同时返回一致的结果格式,让调用方无需区分函数类型。

基础实现方案

直接封装一个高阶函数,内部通过try/catch捕获同步错误,借助await自动处理异步Promise的resolve/reject,最终返回包含错误和结果的统一格式(这里用[error, result]数组,你也可以换成对象格式):

function failSafe(fn) {
  return async function(...args) {
    try {
      // 执行传入的函数,不管同步还是异步
      const result = fn(...args);
      // await兼容同步值(直接返回)和Promise(等待完成)
      return [null, await result];
    } catch (err) {
      // 捕获同步抛出的错误,或await Promise时的reject错误
      return [err, null];
    }
  };
}

测试用例验证

同步函数场景

// 同步函数:输入负数抛出错误
const syncDouble = (num) => {
  if (num < 0) throw new Error("不允许输入负数");
  return num * 2;
};

const safeSyncDouble = failSafe(syncDouble);

// 调用方式统一用await
(async () => {
  console.log(await safeSyncDouble(6)); // [null, 12]
  console.log(await safeSyncDouble(-2)); // [Error: 不允许输入负数, null]
})();

异步函数场景

// 异步函数:输入负数reject
const asyncDouble = async (num) => {
  if (num < 0) throw new Error("不允许输入负数");
  // 模拟异步操作
  return new Promise(resolve => setTimeout(() => resolve(num * 2), 100));
};

const safeAsyncDouble = failSafe(asyncDouble);

safeAsyncDouble(8).then(console.log); // [null, 16]
safeAsyncDouble(-5).then(console.log); // [Error: 不允许输入负数, null]

可选优化:自定义错误处理

如果需要对捕获的错误做统一处理(比如格式化、补充信息),可以增加一个错误处理参数:

function failSafe(fn, errorHandler = (err) => err) {
  return async function(...args) {
    try {
      const result = fn(...args);
      return [null, await result];
    } catch (err) {
      // 调用自定义错误处理函数
      const handledError = errorHandler(err);
      return [handledError, null];
    }
  };
}

// 使用示例:将错误转为自定义格式
const safeFn = failSafe(asyncDouble, (err) => ({
  code: "INVALID_INPUT",
  message: err.message
}));

safeFn(-3).then(console.log); // [{ code: "INVALID_INPUT", message: "不允许输入负数" }, null]

实现原理说明

  1. 统一执行逻辑:不管传入的是同步还是异步函数,都先执行获取结果。
  2. await的兼容性:await不仅能等待Promise完成,遇到非Promise值会直接返回该值,完美兼容同步场景。
  3. 错误统一捕获:try/catch既可以捕获同步函数执行时抛出的错误,也能捕获await Promise时触发的reject(因为await会把Promise的reject转为抛出错误)。

内容的提问来源于stack exchange,提问作者TOPKAT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:50:16