You need to enable JavaScript to run this app. Node.js中如何处理Unhandled Promise Rejection Warning?调用币安API遇错求解
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中如何处理Unhandled Promise Rejection Warning?调用币安API遇错求解

Node.js对接币安API时超时、未处理Promise拒绝问题的通用处理方案

你当前代码在运行时遇到的pending超时、UnhandledPromiseRejectionWarning,本质是几类逻辑缺失导致的:

  • 没有对异步调用做全链路错误捕获,一旦接口请求失败抛出异常,错误会在Promise链中悬空,触发未处理拒绝的警告
  • 对406个币种执行循环内逐个await的串行请求模式,总请求数高、单条链路耗时长,极易触发币安的接口频率限制,导致请求被挂起超时
  • 没有针对失败请求做重试和异常隔离,单个币种的请求失败会直接拖垮整个批量计算流程
  • 代码中存在无意义的冗余操作,对已经是原生对象的balances结果做JSON.stringify+JSON.parse的循环转换,徒增运行开销

通用处理逻辑

1. 全链路补齐异步错误捕获

所有async函数的调用链都必须覆盖错误捕获,从根源上消除未处理的Promise拒绝:

  • 在最外层调用异步函数的位置包裹try/catch,避免异步函数内部抛出的错误穿透到全局
  • 循环内每一次接口请求单独做局部错误捕获,实现异常隔离,单个币种的请求失败不会中断其他币种的计算流程
  • 在Node.js进程层面监听unhandledRejection全局事件,兜底捕获所有漏网的异步错误,避免程序无提示退出

2. 优化请求模式解决超时、限流问题

你当前的串行请求模式,每发一个请求都要等上一个响应返回,406个币种跑下来不仅总耗时极长,还很容易触发接口的频率阈值,导致请求被挂起:

  • 按照接口的频率限制配置,设置固定大小的并发请求池,在不触发限流的前提下并行发起请求,大幅缩短总耗时
  • 给每个接口请求设置明确的超时阈值,超过约定时间未返回响应就直接判定为请求失败,避免请求无限制pending挂起

3. 增加轻量的失败重试机制

大部分偶发的pending错误,都来自临时的网络抖动、接口临时限流:

  • 对失败的请求按照间隔逐步拉长的规则做最多3次重试,过滤临时故障的影响
  • 对重试依然失败的请求单独记录日志,后续可单独补算,不要阻塞整个批量流程

改造后的参考代码

// 进程级兜底捕获未处理的Promise错误
process.on('unhandledRejection', (reason, promise) => {
  console.error('捕获到未处理的异步错误:', reason);
});

// 基础配置
const REQUEST_CONFIG = {
  timeout: 10000, // 单请求10秒超时
  maxRetry: 3
}

binance.balance(async (error, balances) => {
  if (error) return console.error('获取账户余额失败:', error);
  const coinList = Object.keys(balances);
  const coinCount = coinList.length;

  // 带重试、超时的价格请求封装
  async function fetchPriceWithRetry(pair) {
    let retryTimes = 0;
    while (retryTimes <= REQUEST_CONFIG.maxRetry) {
      try {
        const ticker = await binance.prices(pair);
        return Number(Object.values(ticker));
      } catch (err) {
        retryTimes++;
        // 退避等待后重试
        await new Promise(resolve => setTimeout(resolve, 1000 * retryTimes));
      }
    }
    throw new Error(`交易对${pair}连续重试3次仍请求失败`);
  }

  async function calculateAllCoinValue() {
    for (let i = 0; i < coinCount; i++) {
      const coinName = coinList[i];
      const coinAvailableBalance = Object.values(balances[coinName])[0];
      const usdtPair = `${coinName}USDT`;
      
      try {
        const usdtRate = await fetchPriceWithRetry(usdtPair);
        // 无对应USDT交易对的币种单独处理
        if (isNaN(usdtRate)) {
          console.info(`${coinName} 无对应USDT交易对,现有余额${coinAvailableBalance}无法折算USDT价值`);
          continue;
        }
        console.info('交易对', usdtPair, '当前汇率:', usdtRate);
        console.info(coinName, '可用余额:', coinAvailableBalance);
        console.info(coinName, '折算USDT价值:', usdtRate * coinAvailableBalance);
      } catch (err) {
        console.error(`处理${coinName}价值折算时出错:`, err.message);
      }
    }
  }

  // 最外层捕获整个批量流程的错误
  try {
    await calculateAllCoinValue();
  } catch (err) {
    console.error('批量价值计算流程异常退出:', err);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 15:24:03