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

Angular+Electron离线微服务请求资源耗尽问题解决方案咨询

解决方案

1. 提前检测服务可达性,从根源减少无效请求

在发送定期POST请求前,先判断服务是否可用,避免向离线服务发送请求:

  • 用navigator.onLine快速判断设备联网状态(注意:仅判断设备是否联网,无法确认服务是否在线)。
  • 配合短超时HEAD探测:正式POST前,先向微服务健康检查接口发送HEAD请求,设置1-2秒超时,仅当探测成功时才发送正式请求。

示例代码:

async function isServiceReachable(): Promise<boolean> {
  try {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 2000);
    await fetch('https://your-service/health', {
      method: 'HEAD',
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    return true;
  } catch (err) {
    return false;
  }
}

// 定期发送请求逻辑
setInterval(async () => {
  if (await isServiceReachable()) {
    fetch('https://your-service/endpoint', {
      method: 'POST',
      body: JSON.stringify(yourData),
      keepalive: true // 允许请求在后台完成(无需等待响应)
    }).catch(() => {}); // 忽略错误,因无需响应
  }
}, 10000); // 10秒间隔

2. 给每个请求设置强制超时+主动终止

即使发送了请求,也要通过AbortController强制终止超时请求,避免请求长期pending占用资源(包括浏览器自动发送的预检请求):

示例代码:

function sendPostRequest(data: any) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => {
    controller.abort(); // 超时主动终止请求
    console.log('请求超时,已终止');
  }, 5000); // 设置5秒超时

  fetch('https://your-service/endpoint', {
    method: 'POST',
    body: JSON.stringify(data),
    signal: controller.signal,
    keepalive: true
  })
  .then(() => clearTimeout(timeoutId)) // 请求成功则清除超时器
  .catch((err) => {
    clearTimeout(timeoutId);
    // 仅打印非终止类错误
    if (err.name !== 'AbortError') {
      console.warn('请求失败:', err);
    }
  });
}

// 定期调用
setInterval(() => sendPostRequest(yourData), 10000);

3. 改用Electron主进程net模块处理请求

将请求逻辑移到Electron主进程,用net模块发送请求,渲染进程通过IPC调用主进程完成操作。这样请求会在主进程IO线程处理,不会阻塞Angular所在的渲染进程UI:

主进程代码(main.ts):

const { app, ipcMain, net } = require('electron');

ipcMain.handle('send-post-request', (_, data) => {
  return new Promise((resolve) => {
    const request = net.request({
      method: 'POST',
      url: 'https://your-service/endpoint'
    });

    // 5秒超时自动终止请求
    request.setTimeout(5000, () => {
      request.abort();
      resolve('超时终止');
    });

    request.on('response', () => {
      request.destroy(); // 无需响应,直接销毁请求
      resolve('请求发送成功');
    });

    request.on('error', () => {
      request.destroy();
      resolve('请求失败');
    });

    request.write(JSON.stringify(data));
    request.end();
  });
});

渲染进程Angular代码:

import { ipcRenderer } from 'electron';

async function sendRequest(data: any) {
  try {
    await ipcRenderer.invoke('send-post-request', data);
  } catch (err) {
    console.warn('请求处理失败:', err);
  }
}

// 定期调用
setInterval(() => sendRequest(yourData), 10000);

4. 实现请求队列的限流与清理

维护一个请求队列,限制并发请求数量,并定期清理超时待发请求,避免队列堆积:

  • 设置最大并发数(如5个),超过的请求存入队列等待。
  • 定期清理队列中超过指定时间的待发请求。

示例代码:

class RequestQueue {
  private queue: (() => Promise<void>)[] = [];
  private activeCount = 0;
  private maxActive = 5; // 最大并发数
  private cleanupInterval: NodeJS.Timeout;

  constructor() {
    // 每30秒清理一次5分钟以上的待发请求
    this.cleanupInterval = setInterval(() => {
      this.queue = this.queue.filter(task => {
        return (task as any).timestamp > Date.now() - 300000;
      });
    }, 30000);
  }

  addTask(task: () => Promise<void>) {
    (task as any).timestamp = Date.now();
    this.queue.push(task);
    this.processQueue();
  }

  private async processQueue() {
    while (this.activeCount < this.maxActive && this.queue.length > 0) {
      const task = this.queue.shift();
      if (!task) continue;
      this.activeCount++;
      try {
        await task();
      } catch (err) {
        console.warn('任务执行失败:', err);
      } finally {
        this.activeCount--;
        this.processQueue();
      }
    }
  }

  destroy() {
    clearInterval(this.cleanupInterval);
    this.queue = [];
  }
}

// 使用队列
const requestQueue = new RequestQueue();

setInterval(() => {
  requestQueue.addTask(async () => {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000);
    try {
      await fetch('https://your-service/endpoint', {
        method: 'POST',
        body: JSON.stringify(yourData),
        signal: controller.signal,
        keepalive: true
      });
      clearTimeout(timeoutId);
    } catch (err) {
      clearTimeout(timeoutId);
    }
  });
}, 10000);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:15:33