Skip to content

Commit 3feb6c1

Browse files
committed
feat: add chapter3, chapter4 and chapter5 exercises
1 parent a98d26b commit 3feb6c1

File tree

11 files changed

+465
-0
lines changed

11 files changed

+465
-0
lines changed

chapter3-callbacks/3.2/index.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const { EventEmitter } = require("events");
2+
3+
const ticker = (time, cb) => {
4+
const emitter = new EventEmitter();
5+
let ticks = 0;
6+
process.nextTick(() => emitter.emit("start"));
7+
if (time % 5 === 0) {
8+
emitter.emit("error", "Dividing by 5");
9+
return
10+
}
11+
12+
const interval = setInterval(() => {
13+
if (Date.now() % 5 === 0) {
14+
emitter.emit("error", "Dividing by 5");
15+
}
16+
emitter.emit("tick");
17+
ticks++;
18+
}, 50);
19+
setTimeout(() => {
20+
clearInterval(interval);
21+
cb(ticks);
22+
}, time);
23+
return emitter;
24+
};
25+
26+
const emitter = ticker(324, (ticks) => {
27+
console.log("total number of ticks ", ticks);
28+
});
29+
emitter.on("tick", () => {
30+
console.log("tick");
31+
});
32+
33+
emitter.on("start", () => {
34+
console.log("start called");
35+
});
36+
emitter.on("error", (e) => {
37+
console.error("Error happened", e);
38+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"use strict";
2+
const fs = require("fs");
3+
const path = require("path");
4+
5+
let running = 1;
6+
const result = [];
7+
const listNestedFiles = (dir, cb) => {
8+
if (running === 0) {
9+
return cb(null, result);
10+
}
11+
fs.readdir(dir, "utf-8", (err, files) => {
12+
if (err) {
13+
return cb(err);
14+
}
15+
for (let i = 0; i < files.length; i++) {
16+
const file = files[i];
17+
fs.lstat(dir + "/" + file, (err, stats) => {
18+
if (err) {
19+
return cb(err);
20+
}
21+
if (stats.isDirectory()) {
22+
running++;
23+
process.nextTick(() => listNestedFiles(dir + "/" + file, cb));
24+
} else {
25+
result.push(file);
26+
}
27+
if (i === files.length - 1) {
28+
running--;
29+
}
30+
if (i === files.length - 1 && running === 0) {
31+
cb(null, result);
32+
}
33+
});
34+
}
35+
});
36+
};
37+
38+
const listNestedFilesPromisified = async (dir, cb) => {
39+
try {
40+
const result = await recursivelyFind(dir);
41+
return cb(null, result.flat(Infinity));
42+
} catch (err) {
43+
cb(err);
44+
}
45+
};
46+
47+
const fsPromisified = require("fs/promises");
48+
const recursivelyFind = async (dir) => {
49+
try {
50+
const files = await fsPromisified.readdir(dir, "utf-8");
51+
return Promise.all(
52+
files.map((file) => recursivelyFind(path.join(dir, file)))
53+
);
54+
} catch (err) {
55+
if (err.code === "ENOTDIR") {
56+
return path.basename(dir);
57+
}
58+
throw new Error("Somethin went wrong ", err);
59+
}
60+
};
61+
62+
listNestedFilesPromisified(
63+
"../",
64+
(err, dat) => {
65+
if (err) {
66+
console.log(err);
67+
}
68+
console.log(dat.length);
69+
}
70+
);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"use strict";
2+
const fs = require("fs");
3+
const path = require("path");
4+
5+
const result = [];
6+
let running = 1;
7+
const recursiveFind = (dir, keyword, cb) => {
8+
fs.readdir(dir, "utf-8", (err, files) => {
9+
if (err) {
10+
return cb(err);
11+
}
12+
files.forEach((file, index) => {
13+
fs.lstat(path.join(dir, file), (err, stats) => {
14+
if (err) {
15+
return cb(err);
16+
}
17+
if (stats.isDirectory()) {
18+
running++;
19+
process.nextTick(() =>
20+
recursiveFind(path.join(dir, file), keyword, cb)
21+
);
22+
if (index === files.length - 1) {
23+
running--;
24+
}
25+
} else {
26+
fs.readFile(path.join(dir, file), "utf-8", (err, data) => {
27+
if (err) {
28+
return cb(err);
29+
}
30+
if (data.includes(keyword)) {
31+
result.push(path.join(dir, file));
32+
}
33+
if (index === files.length - 1) {
34+
running--;
35+
}
36+
if (index === files.length - 1 && running === 0) {
37+
return cb(null, result);
38+
}
39+
});
40+
}
41+
});
42+
});
43+
});
44+
};
45+
46+
const fsPromisified = require("fs/promises");
47+
const promisifiedRecursiveFind = async (dir, keyword, cb) => {
48+
try {
49+
const result = await recursive(dir, keyword);
50+
return cb(null, result.flat(Infinity).filter(Boolean));
51+
} catch (err) {
52+
return cb(err);
53+
}
54+
};
55+
56+
const recursive = async (dir, keyword) => {
57+
try {
58+
const files = await fsPromisified.readdir(dir, "utf-8");
59+
return Promise.all(
60+
files.map((file) => recursive(path.join(dir, file), keyword))
61+
);
62+
} catch (err) {
63+
if (err.code === "ENOTDIR") {
64+
const content = await fsPromisified.readFile(dir, "utf-8");
65+
if (content.includes(keyword)) {
66+
return dir;
67+
}
68+
} else {
69+
throw err;
70+
}
71+
}
72+
};
73+
74+
promisifiedRecursiveFind(
75+
"../",
76+
"Batman",
77+
(err, data) => {
78+
if (err) {
79+
console.log(err);
80+
} else {
81+
console.log(data);
82+
}
83+
}
84+
);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
asdasd
2+
Batman
3+
asdasd
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Batman
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
asdasd
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
3+
const promiseAll = (promises) => {
4+
return new Promise(async (resolve, reject) => {
5+
const arr = []
6+
for(let i = 0; i < promises.length; i++) {
7+
try {
8+
const curr = await promises[i]
9+
arr.push(curr)
10+
}
11+
catch(err) {
12+
return reject(err)
13+
}
14+
}
15+
resolve(arr)
16+
})
17+
}
18+
19+
const a = () => {
20+
return Promise.resolve('a')
21+
}
22+
23+
const b = () => {
24+
return Promise.resolve('b')
25+
}
26+
27+
const c = () => {
28+
return Promise.reject(new Error("Error happened"))
29+
}
30+
31+
promiseAll([a(), b(), c()])
32+
.then((data) => console.log(data))
33+
.catch(e => {
34+
console.error(e)
35+
})
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict'
2+
const { EventEmitter } = require('events')
3+
4+
class TaskQueue extends EventEmitter {
5+
constructor(concurrent) {
6+
super();
7+
this.concurrent = concurrent;
8+
}
9+
10+
queue = [];
11+
concurrent = 0;
12+
running = 0;
13+
14+
addTask(task) {
15+
return new Promise((resolve, reject) => {
16+
this.queue.push(async () => {
17+
try {
18+
const curr = await task()
19+
return resolve(curr)
20+
}
21+
catch(err) {
22+
return reject(err)
23+
}
24+
});
25+
this.next()
26+
});
27+
}
28+
29+
async next() {
30+
while (this.running < this.concurrent && this.queue.length !== 0) {
31+
const curr = this.queue.shift();
32+
try {
33+
await curr()
34+
}
35+
finally {
36+
this.running--;
37+
this.next();
38+
}
39+
this.running++;
40+
}
41+
}
42+
}
43+
44+
45+
const delay = (ms) => {
46+
return new Promise((resolve, reject) => {
47+
setTimeout(() => resolve(), ms)
48+
})
49+
}
50+
51+
const taskA = async () => {
52+
console.log("starting task a")
53+
await delay(5000)
54+
return Promise.resolve('a')
55+
}
56+
57+
const taskB = async () => {
58+
console.log("starting task b")
59+
await delay(1000)
60+
return Promise.resolve('b')
61+
}
62+
63+
const taskC = async () => {
64+
console.log("starting task c")
65+
await delay(2000)
66+
return Promise.resolve('c')
67+
}
68+
69+
const queue = new TaskQueue(2)
70+
queue.addTask(taskA).then(data => console.log(data))
71+
queue.addTask(taskB).then(data => console.log(data))
72+
queue.addTask(taskC).then(data => console.log(data))

0 commit comments

Comments
 (0)