-
Notifications
You must be signed in to change notification settings - Fork 0
/
fetcher.ts
58 lines (53 loc) · 1.48 KB
/
fetcher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import Queue from 'queue';
import https from 'https';
export class Fetcher {
counter = 0;
queue = Queue({results: []});
async controlConcurrency(fn: Function, concurrency: number) {
return new Promise(resolve => {
this.queue.push(async () => {
this.counter++;
const result = await fn();
resolve(result);
if (this.queue.length > 0) {
this.queue.shift()();
}
});
if (this.counter < concurrency) {
this.queue.shift()();
}
});
}
async runInParallel(urls: string[], concurrency: number) {
const promises: Promise<any>[] = urls.map(url => {
return this.controlConcurrency(async () => {
try {
const data = await this.sendRequest(url);
return data;
} catch (e) {
console.log(e);
return {};
}
}, concurrency);
});
return await Promise.all(promises);
}
sendRequest(url: string) {
return new Promise((resolve, reject) => {
const lib = https;
const request = lib.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(
new Error(
'Failed to load page, status code: ' + response.statusCode
)
);
}
const body = [];
response.on('data', chunk => body.push(chunk));
response.on('end', () => resolve(body.join('')));
});
request.on('error', err => reject(err));
});
}
}