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

Node.js中函数执行出错时如何重新调用该函数?

在Node.js中处理函数执行错误并重试的方案

嘿,针对你提出的「函数执行出错时如何重新调用」的问题,我结合你给出的代码示例,整理了一套实用的解决方案,主要围绕封装通用重试逻辑来处理异步操作的错误重试:

一、先封装一个通用的回调风格重试工具函数

因为你的代码里用的是回调式的异步API(比如client.getAllOffers和connection.query),我们可以写一个通用工具函数来帮我们自动处理重试,不用每个函数都写重复的逻辑:

// 通用重试函数:包裹回调风格的异步函数,支持自动重试
function retryAsync(fn, args, maxRetries = 3, delay = 1000, currentRetry = 0) {
  return new Promise((resolve, reject) => {
    // 调用目标异步函数
    fn(...args, (err, result) => {
      if (err) {
        // 判断是否还有重试次数
        if (currentRetry < maxRetries) {
          console.log(`操作失败,${delay}ms后进行第${currentRetry + 1}次重试 | 错误信息:${err.message}`);
          // 延迟后递归调用重试
          setTimeout(() => {
            retryAsync(fn, args, maxRetries, delay, currentRetry + 1)
              .then(resolve)
              .catch(reject);
          }, delay);
        } else {
          // 重试耗尽,抛出最终错误
          reject(new Error(`已重试${maxRetries}次仍失败,终止操作:${err.message}`));
        }
      } else {
        // 操作成功,返回结果
        resolve(result);
      }
    });
  });
}

二、改造你的业务代码,接入重试逻辑

接下来我们把原代码里的异步操作都用这个重试函数包裹,同时改用async/await让代码更易读(避免回调地狱):

app.get('/', async function (req, res) {
  try {
    // 对getAllOffers接口调用应用重试逻辑(最多重试3次,间隔1.5s)
    const resp = await retryAsync(client.getAllOffers, [null], 3, 1500);
    const offer = JSON.parse(resp);
    const offerCount = offer.allOffersList.length;
    
    res.send(offer);

    // 遍历插入数据库,每个插入操作都加重试
    for (let i = 0; i < offerCount; i++) {
      const stmt = "INSERT INTO offers(description,start_time,end_time) VALUES (?, ?, ?)";
      const insertParams = [
        offer.allOffersList[i].description,
        offer.allOffersList[i].startTime,
        offer.allOffersList[i].endTime
      ];

      // 数据库插入最多重试2次,间隔1s
      await retryAsync(connection.query, [stmt, insertParams], 2, 1000);
      console.log(`第${i + 1}条优惠记录插入成功`);
    }
  } catch (err) {
    // 捕获所有最终失败的错误,返回给客户端
    console.error('操作最终失败:', err);
    res.status(500).send('服务器内部错误,请稍后重试');
  }
});

三、进阶优化建议

  • 区分可重试错误:不是所有错误都值得重试,比如SQL语法错误、参数错误这类永久错误,重试多少次都没用。你可以在重试函数里加错误判断:
    // 在retryAsync的err分支里添加判断
    const retryableErrors = ['network', 'timeout', 'connection'];
    const isRetryable = retryableErrors.some(keyword => err.message.includes(keyword));
    
    if (isRetryable && currentRetry < maxRetries) {
      // 只重试临时错误
      setTimeout(/* 重试逻辑 */);
    } else {
      reject(err); // 非重试错误直接抛出
    }
    
  • 指数退避策略:可以把重试间隔改成指数增长(比如1s→2s→4s),避免短时间内频繁请求给服务造成压力:
    setTimeout(() => {
      retryAsync(fn, args, maxRetries, delay * 2, currentRetry + 1)
        .then(resolve)
        .catch(reject);
    }, delay);
    
  • 避免并发问题:如果你的插入操作很多,也可以考虑用批量插入或者控制并发数,避免同时发起大量数据库请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:48:27