密集调用, 缓慢执行---一个特殊的延迟函数

本文介绍了一种解决Node.js爬虫因大量并发请求导致socket连接耗尽的问题的方法。通过自定义延迟调用函数实现了请求的节流,确保所有请求都能得到执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间开发过程中遇到一个特殊的需求:
起初写了一个简单的爬虫, 用来爬取本地showdoc文档中所有的接口数据. 先随机访问一个页面, 拿到侧边栏的所有连接, 然后写一个循环, 使用node访问各个连接依次拿到所对应的数据
代码类似

Promise.all(urls.map(url => get(url))).then(resultArr => {
    ...
})

但是这时出现了一个问题, 因为接口数量比较多 (大概500个) 所以get方法一次发送了500个左右请求, 结果node会报错 socket hung up , 导致部分请求无法正常返回数据, 原因大概是请求太多 socket 被耗尽了(也可能是服务器的原因), 第一个想到的就是节流/去抖函数, 但是网上找了一圈, 发现没有合适我这个需求的, 我需要在短时间多次调用,
然后在之后的一段时间,把积累的调用次数慢慢的执行完, 一个都不能少!
没办法,只好自己写了一个. 在这里记录一下.


function delayCall(fn, delay) {
  let arr = [] //用来储存每次调用传入的参数
  //延迟调用函数
  const _delayCall = function(context) {
    setTimeout(() => {
      //队列最前面的参数出队列
      arr.shift()
      //如果队列中还有未调用的参数, 则递归调用直到耗尽队列中的参数
      if(arr.length > 0) {
        fn.apply(context, arr[0])
        _delayCall(context)
      }
    }, delay)
  }
  return function() {
    const context = this
    arr.push(arguments)
    if(arr.length === 1) {
      //第一次调用时立即调用
      fn.apply(context, arguments)
      _delayCall(context)
    }
  }
}







可以用一段代码测试

let i = 5
const delay = delayCall(function(e){ console.log(e) }, 500)
while(i--) delay(i)


这个函数可以实现密集调用, 缓慢执行的效果. 不介意的就收藏下,说不定以后用的着呢 ^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值