You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JavaScript新手:高频调用REST API触发Socket错误的解决咨询

解决高频REST POST调用导致的Socket错误问题

嘿,这个坑我之前踩过!连续高频调用API的时候,不管是服务端的并发限制,还是客户端的Socket连接池被耗尽,都容易触发这类错误。针对你的700行CSV数据场景,给你几个实用的调整方案,按优先级和复杂度排序:

1. 优先尝试:批量上传数据(最优解)

如果你的REST服务支持接收批量数据,这绝对是最好的选择。把多行CSV数据打包成一个请求发送,直接把请求次数从700次降到十几到几十次,从根源上解决调用频繁的问题。

举个代码示例:

// 假设你已经把CSV解析成了数组dataArray
const batchSize = 50; // 每50条数据发一次请求,可根据服务端承受能力调整

for (let i = 0; i < dataArray.length; i += batchSize) {
  const batchData = dataArray.slice(i, i + batchSize);
  
  try {
    await fetch('你的API地址', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(batchData)
    });
    // 批次之间可以加个短延迟,进一步降低压力
    await new Promise(resolve => setTimeout(resolve, 50));
  } catch (err) {
    console.error(`上传批次 ${Math.floor(i/batchSize) + 1} 失败:`, err);
    // 这里可以加重试逻辑,后面会提到
  }
}

注意:如果服务端还不支持批量接口,最好和后端同学沟通一下,批量处理不管是前端还是后端效率都会高很多。

2. 并发控制(适合无法批量的场景)

如果必须逐行调用API,那就要控制同时发起的请求数量,避免一下子占满所有Socket连接。你可以用npm上的p-limit包来轻松实现,这是Node.js生态里处理并发限制的常用工具。

步骤如下:
首先安装依赖:

npm install p-limit

然后编写代码:

const pLimit = require('p-limit');
const limit = pLimit(5); // 限制同时最多5个请求并发

// 把每个上传任务包装成受限制的异步函数
const uploadTasks = dataArray.map(item => limit(async () => {
  try {
    await fetch('你的API地址', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(item)
    });
  } catch (err) {
    console.error(`上传数据失败:`, err);
  }
}));

// 等待所有任务完成
await Promise.all(uploadTasks);

这个方法既不会像逐行同步调用那样慢,又不会因为并发太高触发错误,平衡了效率和稳定性。

3. 简单临时方案:添加固定延迟

如果上面两种方案暂时没法实现,最快速的临时解决方法就是在每次请求后加一个固定延迟,降低调用频率。

写个简单的sleep函数:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// 然后在每次上传后调用
for (const item of dataArray) {
  await fetch('你的API地址', { /* 请求配置 */ });
  await sleep(100); // 等待100毫秒,可根据实际情况调整
}

这个方法虽然简单,但效率最低,700条数据要等一分多钟,适合临时救急。

4. 锦上添花:添加错误重试机制

不管用上面哪种方法,都建议加上重试逻辑——网络请求偶尔失败很正常,尤其是高频调用时。可以用指数退避的方式,失败后等待一段时间再重试,每次等待时间翻倍。

示例重试函数:

async function fetchWithRetry(url, options, retries = 3, delay = 1000) {
  try {
    const response = await fetch(url, options);
    if (!response.ok) {
      throw new Error(`HTTP错误: ${response.status}`);
    }
    return response;
  } catch (err) {
    if (retries > 0) {
      console.log(`请求失败,${delay}毫秒后重试,剩余重试次数:${retries}`);
      await new Promise(resolve => setTimeout(resolve, delay));
      return fetchWithRetry(url, options, retries - 1, delay * 2);
    }
    throw err; // 重试耗尽后抛出错误,方便后续处理
  }
}

把之前的fetch替换成这个函数,遇到Socket错误或者HTTP错误时会自动重试,大大提高上传成功率。


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

火山引擎 最新活动