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
相关产品推荐
相关产品推荐

