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

module.exports中调用async.retry重试时抛出无效参数错误求助

解决async.retry抛出"Invalid arguments"错误的问题

我看到你遇到的问题了,咱们一步步拆解根源并修复:

核心错误原因

1. 错误传递任务函数给async.retry

你当前代码里写的是:

async.retry({ times: 3, interval: 200 }, module.exports.sendEnergy(url, body), function (err, result) { ... })

这里module.exports.sendEnergy(url, body)是直接执行了函数,而不是传递一个可被重试调用的函数引用。sendEnergy执行后返回undefined(因为你没写return),async.retry拿到undefined就会抛出"参数无效"的错误。

2. sendEnergy未遵循异步流程规范

async.retry要求重试的任务函数必须满足以下两种规范之一:

  • 接受一个回调参数(function(callback) { ... }),在异步操作完成时调用callback(err, result)传递结果/错误;
  • 返回一个Promise,让async.retry可以等待异步操作完成。

而你现在的sendEnergy里,request.post的回调只是内部处理逻辑,没有把错误或结果传递出去,async.retry根本感知不到异步操作的完成状态,也捕获不到错误。

修复后的代码

我给你两种实用方案,选你习惯的风格即可:

方案1:用Promise封装sendEnergy(推荐)

先安装request-promise(request已被官方弃用,也可以换成axios/node-fetch这类现代库),然后修改代码:

const rp = require('request-promise'); // 先执行 npm install request-promise

module.exports = { 
  sendMessageToNewModel: (body, id) => { 
    let url = ''; 
    switch (id) { 
      case 'energy': 
        url = 'http://myapi.test.api/appliance'; 
        break; 
      case 'device-energy': 
        url = 'http://myapi.test.api/device'; 
        break; 
      default:
        // 增加默认分支避免url为空
        throw new Error('Invalid id provided');
    } 
    // 用箭头函数包裹,确保每次重试都会重新调用sendEnergy
    async.retry({ times: 3, interval: 200 }, () => module.exports.sendEnergy(url, body), function (err, result) { 
      if (err) {
        console.error('所有重试均失败:', err);
        return;
      }
      console.log('请求成功:', result); 
    }); 
  }, 
  sendEnergy: (url, body) => { 
    const options = { 
      url: url, 
      json: true, 
      body: body,
      resolveWithFullResponse: true // 配置后可拿到完整响应对象
    }; 
    // 返回Promise,async.retry会自动处理异步流程
    return rp.post(options)
      .then(res => res.statusCode)
      .catch(err => {
        // 抛出错误让async.retry捕获并重试
        throw err;
      });
  } 
}

方案2:用回调风格适配async.retry

如果你不想用Promise,也可以修改sendEnergy接受回调参数:

const request = require('request');

module.exports = { 
  sendMessageToNewModel: (body, id) => { 
    let url = ''; 
    switch (id) { 
      case 'energy': 
        url = 'http://myapi.test.api/appliance'; 
        break; 
      case 'device-energy': 
        url = 'http://myapi.test.api/device'; 
        break; 
      default:
        throw new Error('Invalid id provided');
    } 
    // 传递带callback的函数给async.retry
    async.retry({ times: 3, interval: 200 }, function(callback) {
      module.exports.sendEnergy(url, body, callback);
    }, function (err, result) { 
      if (err) {
        console.error('所有重试均失败:', err);
        return;
      }
      console.log('请求成功:', result); 
    }); 
  }, 
  sendEnergy: (url, body, callback) => { 
    const options = { url: url, json: true, body: body }; 
    request.post(options, (err, res, body) => { 
      if (err) {
        // 将错误传递给callback,让async.retry捕获并重试
        return callback(err);
      } 
      // 将成功结果传递给callback
      callback(null, res.statusCode);
    }); 
  } 
}

额外提示

  • 变量url记得用let声明,避免变成全局变量引发意外问题;
  • 重试间隔200秒偏长,一般API重试间隔设置为几秒到几十秒即可,你可以根据实际场景调整;
  • request库已被官方标记为弃用,建议逐步迁移到axios、node-fetch等维护活跃的库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 17:12:43