├── README.md ├── call-stack.js ├── event-loop.js ├── events.js ├── exec.js ├── fork-client.js ├── fork.js ├── performance.js ├── spawn.js ├── thread-pool.js ├── timers.js ├── worker-client.js ├── worker-sync.js ├── worker.js ├── worker └── factorial.js └── Упражнение ├── app.js ├── factorial.js ├── fork.js └── worker.js /README.md: -------------------------------------------------------------------------------- 1 | # Первый репозиторий к курсу по основам NodeJS 2 | 3 | [Все курсы на PurpleSchool](https://purpleschool.ru/) -------------------------------------------------------------------------------- /call-stack.js: -------------------------------------------------------------------------------- 1 | const a = 5; 2 | 3 | function b() { 4 | return c(); 5 | } 6 | 7 | function c() { 8 | return d(); 9 | } 10 | 11 | function d() { 12 | console.log(a); 13 | } 14 | 15 | setTimeout(() => { 16 | console.log('Timeout'); 17 | }, 1000) 18 | 19 | b(); -------------------------------------------------------------------------------- /event-loop.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | console.log('Init'); 4 | 5 | setTimeout(() => { 6 | console.log(performance.now(), 'Timeout 0'); 7 | }, 0) 8 | 9 | setImmediate(() => { 10 | console.log('immediate'); 11 | }) 12 | 13 | fs.readFile(__filename, () => { 14 | console.log('file readed'); 15 | setTimeout(() => console.log('Timeout file'), 1000); 16 | }) 17 | 18 | setTimeout(() => { 19 | let sum = 0; 20 | for (let i = 0; i < 1000000000; i++) { 21 | sum++; 22 | } 23 | }, 1000); 24 | 25 | setTimeout(() => { 26 | console.log(performance.now(), 'Timeout 1000'); 27 | }, 1000); 28 | 29 | Promise.resolve().then(() => { 30 | console.log('Promise'); 31 | }) 32 | 33 | process.nextTick(() => console.log('Tick')); 34 | 35 | console.log('End'); -------------------------------------------------------------------------------- /events.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require('events'); 2 | 3 | var eventEmitter = new EventEmitter(); 4 | 5 | const log = () => { 6 | console.log('Connected'); 7 | } 8 | 9 | eventEmitter.addListener('connection', log); 10 | eventEmitter.emit('connection'); 11 | 12 | // ------- 13 | 14 | eventEmitter.removeListener('connection', log); 15 | // eventEmitter.off('connection', log); 16 | eventEmitter.emit('connection'); 17 | 18 | // ------- 19 | 20 | eventEmitter.on('msg', (data) => { 21 | console.log(`Получил: ${data}`); 22 | }); 23 | eventEmitter.emit('msg', 1); 24 | 25 | //----- 26 | 27 | eventEmitter.once('test', () => { 28 | console.log('Вызовется 1 раз'); 29 | }); 30 | eventEmitter.emit('test'); 31 | eventEmitter.emit('test'); 32 | 33 | //----- 34 | 35 | console.log(eventEmitter.getMaxListeners()); 36 | console.log(eventEmitter.listenerCount('msg')); 37 | console.log(eventEmitter.listeners('msg')); 38 | console.log(eventEmitter.eventNames()); 39 | 40 | //----- 41 | 42 | eventEmitter.setMaxListeners(1); 43 | console.log(eventEmitter.getMaxListeners()); 44 | 45 | //----- 46 | 47 | eventEmitter.once('newListener', (event, listener) => { 48 | console.log(`Добавился ${event} ${listener}`); 49 | }); 50 | 51 | eventEmitter.prependListener('msg', () => { 52 | console.log('prepends'); 53 | }); 54 | // eventEmitter.prependOnceListener('msg', () => { 55 | // console.log('prepends'); 56 | // }); 57 | eventEmitter.emit('msg', '2е сообщение'); 58 | 59 | // -------- 60 | 61 | eventEmitter.on('error', (err) => { 62 | console.log(`Ошибка: ${err.message}`); 63 | }); 64 | eventEmitter.emit('error', new Error('BOOOM!')); 65 | 66 | 67 | // -------- 68 | const target = new EventTarget(); 69 | 70 | const logNode = () => { 71 | console.log('Connected NodeTarget'); 72 | } 73 | 74 | target.addEventListener('connection_node', logNode); 75 | target.dispatchEvent(new Event('connection_node')); -------------------------------------------------------------------------------- /exec.js: -------------------------------------------------------------------------------- 1 | const { exec } = require('child_process'); 2 | 3 | var workerProcess = exec('lss', function (error, stdout, stderr) { 4 | if (error) { 5 | console.log(error); 6 | } 7 | console.log('stdout: ' + stdout); 8 | console.log('stderr: ' + stderr); 9 | }); 10 | 11 | workerProcess.on('exit', function (code) { 12 | console.log('Child process exited with exit code ' + code); 13 | }); -------------------------------------------------------------------------------- /fork-client.js: -------------------------------------------------------------------------------- 1 | process.on('message', (msg) => { 2 | if (msg == 'disconnect') { 3 | process.disconnect(); 4 | return; 5 | } 6 | console.log(`Клиент получил: ${msg}`); 7 | process.send('Pong!'); 8 | }) -------------------------------------------------------------------------------- /fork.js: -------------------------------------------------------------------------------- 1 | const { fork } = require('child_process'); 2 | 3 | const forkProcess = fork('./fork-client.js'); 4 | 5 | forkProcess.on('message', (msg) => { 6 | console.log(`Получено соообщение: ${msg}`); 7 | }); 8 | 9 | forkProcess.on('close', (code) => { 10 | console.log(`Exited: ${code}`); 11 | }); 12 | 13 | forkProcess.send('Ping'); 14 | forkProcess.send('disconnect'); -------------------------------------------------------------------------------- /performance.js: -------------------------------------------------------------------------------- 1 | const perf_hooks = require('perf_hooks'); 2 | 3 | test = perf_hooks.performance.timerify(test); 4 | 5 | const performanceObserver = new perf_hooks.PerformanceObserver((items, observer) => { 6 | console.log(items.getEntries()); 7 | const entry = items.getEntriesByName('slow').pop(); 8 | console.log(`${entry.name}: ${entry.duration}`); 9 | observer.disconnect(); 10 | }); 11 | performanceObserver.observe({ entryTypes: ['measure', 'function'] }); 12 | 13 | function test() { 14 | const arr = []; 15 | for (let i = 0; i < 100000000; i++) { 16 | arr.push(i * i); 17 | } 18 | } 19 | 20 | function slow() { 21 | performance.mark('start'); 22 | const arr = []; 23 | for (let i = 0; i < 100000000; i++) { 24 | arr.push(i * i); 25 | } 26 | performance.mark('end'); 27 | performance.measure('slow', 'start', 'end'); 28 | } 29 | 30 | slow(); 31 | test(); -------------------------------------------------------------------------------- /spawn.js: -------------------------------------------------------------------------------- 1 | const { spawn } = require('child_process'); 2 | 3 | var workerProcess = spawn('ls'); 4 | 5 | workerProcess.stdout.on('data', function (data) { 6 | console.log('stdout: ' + data); 7 | }); 8 | 9 | workerProcess.stderr.on('data', function (data) { 10 | console.log('stderr: ' + data); 11 | }); 12 | 13 | workerProcess.on('close', function (code) { 14 | console.log('child process exited with code ' + code); 15 | }); -------------------------------------------------------------------------------- /thread-pool.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto'); 2 | const https = require('https'); 3 | const start = performance.now(); 4 | 5 | process.env.UV_THREADPOOL_SIZE = 24; 6 | 7 | for (let i = 0; i < 50; i++) { 8 | https.get('https://yandex.ru', (res) => { 9 | res.on('data', () => { }); 10 | res.on('end', () => { 11 | console.log(performance.now() - start); 12 | }); 13 | }); 14 | } 15 | 16 | for (let i = 0; i < 50; i++) { 17 | crypto.pbkdf2('test', 'salt', 100000, 64, 18 | 'sha512', (err, key) => { 19 | console.log(performance.now() - start); 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /timers.js: -------------------------------------------------------------------------------- 1 | // ------ 1 2 | const start = performance.now(); 3 | setTimeout(() => { 4 | console.log('прошла секунда?'); 5 | console.log(performance.now() - start); 6 | }, 1000); 7 | 8 | // ------ 2 9 | function myFunc(arg) { 10 | console.log(`Аргумент => ${arg}`); 11 | } 12 | 13 | setTimeout(myFunc, 1500, 'Хороший'); 14 | 15 | // ------ 3 16 | const timerId = setTimeout(() => { 17 | console.log('BOOM!'); 18 | }, 6000); 19 | 20 | setTimeout(() => { 21 | clearTimeout(timerId); 22 | console.log('Очищено!'); 23 | }, 1000); 24 | 25 | // ------ 4 26 | const intervalId = setInterval(() => { 27 | console.log(performance.now()); 28 | }, 1000); 29 | 30 | setTimeout(() => { 31 | clearInterval(intervalId); 32 | }, 3000); 33 | 34 | // ------ 5 35 | console.log('Перед'); 36 | 37 | setImmediate(() => { 38 | console.log('После всего'); 39 | }); 40 | 41 | console.log('После'); 42 | 43 | 44 | // ------ 6 45 | const timerObj = setTimeout(() => { 46 | console.log('Я запущусь?'); 47 | }, 2000); 48 | timerObj.unref(); 49 | setImmediate(() => { 50 | timerObj.ref(); 51 | }); 52 | -------------------------------------------------------------------------------- /worker-client.js: -------------------------------------------------------------------------------- 1 | const { parentPort, workerData } = require('worker_threads'); 2 | const factorial = require('./worker/factorial.js'); 3 | 4 | const compute = ({ array }) => { 5 | const arr = []; 6 | for (let i = 0; i < 100000000; i++) { 7 | arr.push(i * i); 8 | } 9 | return array.map(el => factorial(el)); 10 | }; 11 | 12 | compute(workerData); 13 | 14 | parentPort.postMessage( 15 | compute(workerData) 16 | ); -------------------------------------------------------------------------------- /worker-sync.js: -------------------------------------------------------------------------------- 1 | const factorial = require('./worker/factorial.js'); 2 | const compute = (array) => { 3 | const arr = []; 4 | for (let i = 0; i < 100000000; i++) { 5 | arr.push(i * i); 6 | } 7 | return array.map(el => factorial(el)); 8 | }; 9 | 10 | const run = async () => { 11 | performance.mark('start'); 12 | 13 | const result = [ 14 | compute([25, 12, 20, 48, 30, 50]), 15 | compute([25, 12, 20, 48, 30, 50]), 16 | compute([25, 12, 20, 48, 30, 50]), 17 | compute([25, 12, 20, 48, 30, 50]), 18 | ]; 19 | console.log(result); 20 | performance.mark('end'); 21 | performance.measure('slow', 'start', 'end'); 22 | console.log(performance.getEntriesByName('slow').pop()) 23 | } 24 | 25 | run(); -------------------------------------------------------------------------------- /worker.js: -------------------------------------------------------------------------------- 1 | const { Worker } = require('worker_threads'); 2 | 3 | const compute = (array) => { 4 | return new Promise((resolve, reject) => { 5 | const worker = new Worker('./worker-client.js', { 6 | workerData: { 7 | array, 8 | } 9 | }); 10 | 11 | worker.on('message', (msg) => { 12 | console.log(worker.threadId); 13 | resolve(msg) 14 | }); 15 | 16 | worker.on('error', (err) => { 17 | reject(err) 18 | }); 19 | 20 | worker.on('exit', () => { 21 | console.log(`Завершил работу`); 22 | }); 23 | }) 24 | }; 25 | 26 | const run = async () => { 27 | performance.mark('start'); 28 | 29 | const result = await Promise.all([ 30 | compute([25, 12, 20, 48, 30, 50]), 31 | compute([25, 12, 20, 48, 30, 50]), 32 | compute([25, 12, 20, 48, 30, 50]), 33 | compute([25, 12, 20, 48, 30, 50]), 34 | ]); 35 | console.log(result); 36 | performance.mark('end'); 37 | performance.measure('slow', 'start', 'end'); 38 | console.log(performance.getEntriesByName('slow').pop()) 39 | } 40 | 41 | run(); 42 | -------------------------------------------------------------------------------- /worker/factorial.js: -------------------------------------------------------------------------------- 1 | module.exports = function factorial(n) { 2 | if (n === 1 || n === 0) { 3 | return 1; 4 | } 5 | return factorial(n - 1) * n; 6 | } -------------------------------------------------------------------------------- /Упражнение/app.js: -------------------------------------------------------------------------------- 1 | const { Worker } = require('worker_threads'); 2 | const { fork } = require('child_process'); 3 | const { performance, PerformanceObserver } = require('perf_hooks'); 4 | const { readFileSync } = require('fs'); 5 | 6 | const file = readFileSync('./file.mp4'); 7 | 8 | const performanceObserver = new PerformanceObserver((items) => { 9 | items.getEntries().forEach((entry) => { 10 | console.log(`${entry.name}: ${entry.duration}`); 11 | }); 12 | }); 13 | performanceObserver.observe({ entryTypes: ['measure'] }); 14 | 15 | const workerFunction = (array) => { 16 | return new Promise((resolve, reject) => { 17 | performance.mark('worker start'); 18 | const worker = new Worker('./worker.js', { 19 | workerData: { 20 | array, 21 | file 22 | } 23 | }); 24 | worker.on('message', (msg) => { 25 | performance.mark('worker end'); 26 | performance.measure('worker', 'worker start', 'worker end'); 27 | 28 | resolve(msg); 29 | }); 30 | }); 31 | }; 32 | 33 | const forkFunction = (array) => { 34 | return new Promise((resolve, reject) => { 35 | performance.mark('fork start'); 36 | const forkProcess = fork('./fork.js'); 37 | forkProcess.send({ array, file }); 38 | forkProcess.on('message', (msg) => { 39 | performance.mark('fork end'); 40 | performance.measure('fork', 'fork start', 'fork end'); 41 | resolve(msg); 42 | }); 43 | 44 | }); 45 | }; 46 | 47 | const main = async () => { 48 | try { 49 | await workerFunction([25, 20, 19, 48, 30, 50]); 50 | await forkFunction([25, 20, 19, 48, 30, 50]); 51 | } catch (e) { 52 | console.error(e.message); 53 | } 54 | }; 55 | 56 | main(); -------------------------------------------------------------------------------- /Упражнение/factorial.js: -------------------------------------------------------------------------------- 1 | function factorial(n) { 2 | if (n == 1 || n == 0) { 3 | return 1; 4 | } 5 | return factorial(n - 1) * n; 6 | } 7 | 8 | function compute({ array }) { 9 | const arr = []; 10 | for (let i = 0; i < 100000000; i++) { 11 | arr.push(i * i); 12 | } 13 | return array.map(el => factorial(el)); 14 | }; 15 | 16 | module.exports = { factorial, compute } -------------------------------------------------------------------------------- /Упражнение/fork.js: -------------------------------------------------------------------------------- 1 | const { compute } = require('./factorial'); 2 | 3 | process.on('message', (msg) => { 4 | process.send(compute(msg)); 5 | process.disconnect(); 6 | }); 7 | -------------------------------------------------------------------------------- /Упражнение/worker.js: -------------------------------------------------------------------------------- 1 | const { parentPort, workerData } = require('worker_threads'); 2 | const { compute } = require('./factorial'); 3 | 4 | parentPort.postMessage(compute(workerData)) 5 | --------------------------------------------------------------------------------