

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Difficulty: 7
click for more info
Not enough gems
Cost: 6 gems
1: Concurrency
incomplete
2: Max Pages
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
Your web crawler works – but it's crawling pages one at a time. It would take us a really long time to crawl a large website. Let's make it faster using Promise-based concurrency. This is another long step, but don't get discouraged!
We will be using the p-limit package to help us add concurrency to our project.
npm install p-limitFollow the instructions in the p-limit documentation to import the package.
baseURL (the starting URL)
pages (our Record of page visit counts)
limit (a function created with pLimit(maxConcurrency))
private addPageVisit(normalizedURL: string): booleanTake a normalized URL
Update the pages object like you did before
Return true if it's the first time visiting the page, otherwise return false
private async getHTML(currentURL: string): Promise<string>Wrap the same fetch logic and error handling we had before in our new limit function and return the result:
return await this.limit(async () => {
// same fetch logic and error handling as before
// return res.text() here
});Wrapping our getHTML logic inside the limit function, gives us control over how many concurrent fetches run at once. This can be adjusted by changing the value of maxConcurrency. Keeping this low helps us avoid hammering the target server with too many requests.
private async crawlPage(currentURL: string): Promise<void>Keep the same-domain check: if currentURL has a different hostname from baseURL, return before recording a visit or fetching the page
Call your new addPageVisit method, if it is not a new page return early
Get the HTML from the current URL using your new getHTML method
Get all the URLs from the response body HTML, resolving them relative to currentURL
Create an array of promises for each URL by calling this.crawlPage(nextURL)
Use Promise.all() to await all the concurrent crawl promises
Creates a ConcurrentCrawler instance
Calls and awaits the crawl() method
Returns the final pages Record
Make sure you're not crawling the same page multiple times. That's why my addPageVisit method returns a boolean: to indicate if it's the first time we've seen the page.
Use Promise.all() to handle multiple concurrent requests efficiently