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

Node.js中如何让request响应体在多个JS文件中复用?

如何单次调用Web服务并在多个JS文件复用返回数据

这是个很典型的复用API数据的需求,核心就是把请求逻辑封装起来,确保只发一次请求,然后把结果缓存好给各个文件用。我给你几个实用的实现方式,适配不同的JS环境:

方案1:Node.js CommonJS环境(基于你用的request库)

把API请求封装成一个单例模块,缓存请求结果,同时处理并发请求避免重复调用:

// apiService.js
const request = require('request');

// 缓存请求到的body数据
let cachedBody = null;
// 标记是否有请求正在进行,避免并发重复发起
let isRequestInProgress = false;

function fetchData() {
  return new Promise((resolve, reject) => {
    // 有缓存直接返回
    if (cachedBody) {
      resolve(cachedBody);
      return;
    }
    // 请求正在进行,等待结果
    if (isRequestInProgress) {
      setTimeout(() => fetchData().then(resolve).catch(reject), 100);
      return;
    }

    isRequestInProgress = true;
    const host = '你的目标主机地址';
    const options = {/* 你的请求配置,比如headers、method等 */};

    request(host, options, (error, response, body) => {
      isRequestInProgress = false;
      if (error) {
        reject(error);
        return;
      }
      // 解析JSON(如果返回的是JSON格式,按需调整)
      cachedBody = JSON.parse(body);
      resolve(cachedBody);
    });
  });
}

module.exports = fetchData;

在其他JS文件里调用,不管多少个文件调用,只会发一次请求:

// file1.js
const fetchData = require('./apiService');

fetchData().then(body => {
  console.log('文件1使用数据:', body);
  // 在这里处理你的业务逻辑
}).catch(err => console.error('请求出错:', err));

// file2.js
const fetchData = require('./apiService');

fetchData().then(body => {
  console.log('文件2使用数据:', body);
}).catch(err => console.error('请求出错:', err));

方案2:ES6模块环境(现代Node.js或浏览器)

如果你的项目用import/export语法,可以用更简洁的Promise缓存方式:

// apiService.js
import request from 'request'; // 或者替换成node-fetch等现代请求库

let cachedBody = null;
// 缓存请求的Promise,避免并发重复请求
let requestPromise = null;

export async function fetchData() {
  if (cachedBody) {
    return cachedBody;
  }
  if (!requestPromise) {
    requestPromise = new Promise((resolve, reject) => {
      const host = '你的目标主机地址';
      const options = {/* 你的请求配置 */};
      request(host, options, (error, response, body) => {
        if (error) {
          reject(error);
          requestPromise = null; // 请求失败后允许重试
          return;
        }
        cachedBody = JSON.parse(body);
        resolve(cachedBody);
      });
    });
  }
  return requestPromise;
}

在其他文件导入使用:

// file1.js
import { fetchData } from './apiService.js';

async function init() {
  try {
    const body = await fetchData();
    console.log('文件1使用数据:', body);
  } catch (err) {
    console.error('请求出错:', err);
  }
}

init();

// file2.js
import { fetchData } from './apiService.js';

fetchData().then(body => {
  console.log('文件2使用数据:', body);
}).catch(err => console.error('请求出错:', err));

方案3:浏览器端实现(用原生fetch API)

如果是前端项目,把请求封装成模块,用浏览器原生的fetch API:

// apiService.js
let cachedBody = null;
let requestPromise = null;

export async function fetchData() {
  if (cachedBody) {
    return cachedBody;
  }
  if (!requestPromise) {
    requestPromise = fetch('你的API完整地址', {
      // 请求配置:method、headers、body等
    })
    .then(response => {
      if (!response.ok) throw new Error(`请求失败:${response.status}`);
      return response.json(); // 直接解析JSON响应
    })
    .then(data => {
      cachedBody = data;
      return data;
    })
    .catch(err => {
      requestPromise = null; // 失败后允许重试
      throw err;
    });
  }
  return requestPromise;
}

在其他前端脚本里导入使用即可,逻辑和上面一致。

额外注意事项

  • 缓存过期:如果数据需要定期更新,可以添加缓存时间戳,下次调用时判断是否过期,过期就清空缓存重新请求。
  • 错误处理:上面的代码在请求失败后会允许重试,你可以根据需求调整,比如是否缓存错误信息,或者限制重试次数。
  • 框架适配:如果用React、Vue等前端框架,也可以把缓存的数据放到全局状态管理工具(比如Pinia、Redux)里,本质还是基于缓存的思路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:38:12