Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsertkov/142ab3ade502567285041a885e54f39c to your computer and use it in GitHub Desktop.
Save tsertkov/142ab3ade502567285041a885e54f39c to your computer and use it in GitHub Desktop.
NodeJs http get downloader with concurrency control
// example
const fetchUrl = fetchUrlFactory(2)
const { content, headers } = await fetchUrl('https://example.com')
// lib
const https = require('https')
function fetcUrlFactory ({ concurrency }) {
let running = 0
let queue = []
function processQueue () {
if (running >= concurrency) return
if (!queue.length) return
const getUrlTask = queue.shift()
running++
if (running.length < concurrency) processQueue()
getUrl(getUrlTask)
}
function getUrl ({ url, resolve, reject }) {
const req = https.get(url, (res) => {
const { statusCode } = res
if (statusCode !== 200) {
reject(new Error(`Unexpected status code: ${statusCode}`))
return
}
let content = ''
res.setEncoding('utf8')
res.on('data', (chunk) => content += chunk)
res.on('end', () => resolve({
content,
headers: res.headers
}))
})
req.on('error', reject)
}
return function fetchUrl (url) {
return new Promise((resolveFn, rejectFn) => {
const resolve = (...args) => {
running--
resolveFn(...args)
processQueue()
}
const reject = (...args) => {
running--
rejectFn(...args)
processQueue()
}
queue.push({ resolve, reject, url })
processQueue()
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment