使用RX JS在每次await fetchResponse调用后设置停顿以适配API限流规则
解决方案
你现有代码的问题是interval(1000)只控制了getData函数的触发间隔,但是函数内部的多个fetchResponse请求是连续串行执行的,没有间隔,会触发接口限频。可以按下面的方式改造:
方案1:最小改动版本
不需要调整原有业务结构,仅给请求方法加一层带延迟的包装即可:
// 封装1秒延迟工具 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // 包装fetchResponse,每次请求完成后自动等待1秒再返回结果 const fetchResponseWithDelay = async (...args) => { const res = await fetchResponse(...args); await delay(1000); return res; } const getData = async() => { let info = { date: new Date(), id: initialId, }; if (fetchInitialResponse(initialId) ) { // 把原来的fetchResponse替换成带延迟的包装方法即可 info['Names'] = await fetchResponseWithDelay( getUrl(ADDRESSOTHERNAMES), process.env.OTHERNAMESFOUND); info['Address'] = await fetchResponseWithDelay( getUrl(ADDRESSADDRESS), process.env.ADDRESSFOUND); info['Individuals'] = await fetchResponseWithDelay( getUrl(ADDRESSINDIVIDUALS), process.env.INDIVIDUALSFOUND); // 剩余所有请求都按同样规则替换 mongoConnect(true, info) } } // 不需要周期性执行getData就直接调用,需要定时跑再保留原来的interval逻辑 getData()
方案2:符合RxJS风格的实现
把请求配置抽成列表,用RxJS流统一控制执行间隔,后续新增请求只需要加配置项即可,不需要重复写冗余代码:
import { from, concatMap, delay } from 'rxjs'; // 统一整理所有请求的配置,对应info存储的key、请求url、入参 const requestConfigs = [ { key: 'Names', url: getUrl(ADDRESSOTHERNAMES), param: process.env.OTHERNAMESFOUND }, { key: 'Address', url: getUrl(ADDRESSADDRESS), param: process.env.ADDRESSFOUND }, { key: 'Individuals', url: getUrl(ADDRESSINDIVIDUALS), param: process.env.INDIVIDUALSFOUND }, // 剩余请求按相同格式补充即可 ]; const getData = async () => { const info = { date: new Date(), id: initialId, }; if (!fetchInitialResponse(initialId)) return; // RxJS控制每个请求间隔1秒串行执行 from(requestConfigs).pipe( concatMap(config => from(fetchResponse(config.url, config.param)).pipe( delay(1000) // 每次请求完成后延迟1秒再执行下一个 ) ) ).subscribe({ next: (res, index) => { info[requestConfigs[index].key] = res; }, complete: () => { // 所有请求执行完成后写入数据库 mongoConnect(true, info); } }) } // 按需调用即可,不需要周期执行就直接调用,需要定时执行再套interval getData()
补充说明
如果接口要求是两次请求发起时间间隔至少1秒,把delay逻辑放到请求发起前即可。如果不需要周期性执行整个getData逻辑,可以直接删除原来的interval订阅。
内容的提问来源于stack exchange,提问作者Vasilii Vakhton
相关产品推荐
相关产品推荐

