递归调用,怎么控制并发量
发布于 7 年前 作者 zhang14725804 3977 次浏览 来自 问答

function spider(url){ //发送请求 //得到数据,处理 … //某些处理得到当前模块下一页的next_url(没有办法直接获取下一个next_url) spider(next_url) }

//先获取各个模块url var main_URLS=[…] main_URLS.forEach(function(url) { spider(url); }) 代码大概就是这个意思

5 回复
// 并发数
const concurrency = 5
function spider(url){
  //发送请求
  i++
  sendReq()
    .then(handleData)
    .then(next_url => {
      i--
      while (i < concurrency) {
        spider(next_url)
      }
    })
    .catch(err => console.error(err))
}

function handleData(data) {
  //  ...
  return next_url
}

//先获取各个模块url
const main_URLS=[…]
let i = 0
main_URLS.forEach(url => {
  spider(url)
})

这样吗?

@chickencyj没有效果,直接卡主不动了

没有效果大概就是main_URLS太大,第一次forEach这里没有控制并发,可以用bluebird的map来控制,我个人想法

我傻了。。。while那里直接把你的next_url丢掉了。。。丢架, 改了一下,应该没大毛病

const main_URLS=[…]
const CONCURRENCY = 5
let urlQueue = main_URLS.slice(0)
let i = 0

const handleData = data => {
  //  ...
  return next_url
}

const sendReq = (URL, urlQueue) => {
  return fetch(URL)
    .then(_res => handleData)
    .then(next_url => {
      i++
      urlQueue.push(next_url)
      if (i === CONCURRENCY) {
        spider(urlQueue)
      }
      return
    })
}
const spider = (urlQueue) => {
  i = 0
  let urls = urlQueue.splice(0, CONCURRENCY)
  urls.forEach(URL => {
    sendReq(URL, urlQueue)
  })
}
spider(urlQueue)
回到顶部