Skip to content

实现一个带并发数限制的fetch请求函数 #10

@bravf

Description

@bravf

这是掘金上看到的一个题目 https://juejin.im/post/5c89d447f265da2dd37c604c 好久不练手了,尝试写了写。

const Deferred = () => {
  let resolve
  let reject
  
  const promise = new Promise( (_resolve, _reject) => {
    resolve = _resolve
    reject = _reject
  } )
  
  return {
    promise,
    resolve,
    reject,
  }
}

const sendRequest = (urls, max, callback) => {
  let currentIndex = 0
  let doneCount = 0
  let poolCount = 0

  const urlsLength = urls.length
  const doneDefer = Deferred()
  doneDefer.promise.then(callback)

  const realRequest = (url, defer) => {
    console.log(`${url} start`)
    setTimeout( () => {
      console.log(`${url} over`)
      defer.resolve()
    }, Math.random() * 10000)
  }
  const request = url => {
    if (currentIndex >= urlsLength) return false
    if (poolCount >= max) return false

    currentIndex ++
    poolCount ++

    const defer = Deferred()
    defer.promise.then(() => {
      doneCount ++
      if (doneCount === urlsLength) {
        doneDefer.resolve()
      }
      else {
        poolCount --
        request(urls[currentIndex])
      }
    })
    realRequest(url, defer)
    return defer
  }

  urls.slice(0, max).map(request)
}

const urls = [
  'baidu_1',
  'baidu_2',
  'baidu_3',
  'baidu_4',
  'baidu_5',
  'baidu_6',
  'baidu_7',
  'baidu_8',
  'baidu_9',
]
sendRequest(urls, 2, ()=>{console.log('all done')})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions