{"id":22951535,"url":"https://github.com/Lifailon/node.js-cheat-sheet-ru","last_synced_at":"2025-08-13T00:32:46.447Z","repository":{"id":259436346,"uuid":"877870495","full_name":"Lifailon/rudocs","owner":"Lifailon","description":"The repository contains documentation in examples on the basic principles of JavaScript/Node.js and GoLang syntax.","archived":false,"fork":false,"pushed_at":"2024-12-04T09:57:11.000Z","size":28,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"rsa","last_synced_at":"2024-12-04T10:38:37.473Z","etag":null,"topics":["go","go-documentation","golang","javascript","javascript-documentation","nodejs"],"latest_commit_sha":null,"homepage":"https://lifailon.github.io","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lifailon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-24T11:43:05.000Z","updated_at":"2024-12-04T09:57:14.000Z","dependencies_parsed_at":"2024-10-25T11:25:44.049Z","dependency_job_id":"d097e86c-ea8a-4823-bb73-ed96548c4a9b","html_url":"https://github.com/Lifailon/rudocs","commit_stats":null,"previous_names":["lifailon/syntaxru"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lifailon%2Frudocs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lifailon%2Frudocs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lifailon%2Frudocs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lifailon%2Frudocs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lifailon","download_url":"https://codeload.github.com/Lifailon/rudocs/tar.gz/refs/heads/rsa","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229717732,"owners_count":18113400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","go-documentation","golang","javascript","javascript-documentation","nodejs"],"created_at":"2024-12-14T15:16:34.590Z","updated_at":"2025-08-13T00:32:46.401Z","avatar_url":"https://github.com/Lifailon.png","language":null,"readme":"![](logo.png)\n\n\u003cp align=\"center\"\u003e\n        \u003ca href=\"https://lifailon.github.io/node-js/\"\u003e\u003cimg title=\"Web version\"src=\"https://img.shields.io/badge/web%20version-%23E34F26.svg?style=for-the-badge\u0026logo=html5\u0026logoColor=white\"\u003e\u003c/a\u003e\n        \u003ca href=\"Node-Cheat-Sheet-Ru.pdf\"\u003e\u003cimg title=\"PDF version\"src=\"https://img.shields.io/badge/pdf_version-DA1F26.svg?style=for-the-badge\u0026logo=Adobe%20Acrobat%20Reader\u0026logoColor=white\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nРепозиторий содержи краткую документацию в примерах по основам синтаксиса `JavaScript` для `Node.js` на **русском языке**.\n\n---\n\nНавигация:\n\n- [Переменные](#переменные)\n- [Типы данных](#типы-данных)\n- [Функции](#функции)\n- [Условия](#условия)\n- [Обработка ошибок](#обработка-ошибок)\n- [Массивы](#массивы)\n- [Объекты](#объекты)\n- [Циклы](#циклы)\n- [Асинхронные операции](#асинхронные-операции)\n- [Регулярные выражения](#регулярные-выражения)\n- [Математические вычисления](#математические-вычисления)\n- [Express](#express)\n- [Axios](#axios)\n- [Fetch](#fetch)\n- [Cheerio](#cheerio)\n- [Puppeteer](#puppeteer)\n\n---\n\n### Переменные\n\nПеременная `var` поддерживает любую область видимости и ее возможно объявить повторно (считается устаревшим методом и рекомендуется не использовать).\n\n```js\nconsole.log(varVariable) // Uncaught ReferenceError: varVariable is not defined (не определена)\nif (true) {\n    var varVariable = true\n}\nconsole.log(varVariable) // true\nvar varVariable = 123\nconsole.log(varVariable) // 123\n```\n\nПеременная `let` позволяет изменять содержимое с другим типом данных (в отличии от `const`), но ограничина областью видимости (в отличии от `var`).\n\n```js\nconsole.log(letVariable) // Uncaught ReferenceError: letVariable is not defined\nif (true) {\n    let letVariable = 'letVariable is defined'\n}\nconsole.log(letVariable) // Uncaught ReferenceError: letVariable is not defined\nlet letVariable = 'string'\nconsole.log(letVariable)\nlet letVariable = 'string' // Uncaught SyntaxError: Identifier 'letVariable' has already been declared (идентификатор уже объявлен)\nletVariable = 123\nconsole.log(letVariable)\n```\n\nПеременная константа `const` требует обязательной инициализации во время объявления, и не позволяет изменять значение переменной после ее объявления.\n\n```js\nconst constVariable = 'string'\nconstVariable = '123' // Uncaught TypeError: Assignment to constant variable (ошибка присвоения значения к постоянной переменной)\n```\n\n### Типы данных\n\n```js\ntypeof 32 // number\ntypeof 3.2 // number\ntypeof 123n // bigint\ntypeof 'text' // string\ntypeof true // boolean\ntypeof false // boolean\ntypeof null // object\ntypeof { key: 'value' } // object\ntypeof [1, 2, 3] // object\ntypeof function() {} // function\ntypeof Symbol('id') // symbol\n```\n\nПреобразовать аргумент в число. Возвращает `NaN`, если преобразование невозможно.\n\n```js\nNumber(\"123\")      // 123\nNumber(\"123.45\")   // 123.45\nNumber(\"abc\")      // NaN\nNumber(undefined)  // NaN\nNumber(true)       // 1\nNumber(false)      // 0\nNumber(null)       // 0\n```\n\nПреобразовать строку в целое число. Прекращает чтение, как только встречает нецифровой символ.\n\n```js\nparseInt(\"123abc\")  // 123\nparseInt(\"12.34\")   // 12\nparseInt(\"abc123\")  // NaN\n```\n\nПреобразовать строку в число с плавающей точкой.\n\n```js\nparseFloat(\"123.45abc\")  // 123.45\nparseFloat(\"abc123.45\")  // NaN\n```\n\nПреобразовать значение в строку.\n\n```js\n(123).toString()   // \"123\"\n(true).toString()  // \"true\"\nString(123)        // \"123\"\nString(true)       // \"true\"\nString(false)      // \"false\"\nString(null)       // \"null\"\nString(undefined)  // \"undefined\"\n```\n\nПреобразовать значение в булевое (логическое) значение. Все значения, кроме `0`, `null`, `NaN`, `undefined` и пустой строки, преобразуются в `true`.\n\n```js\nBoolean(123)        // true\nBoolean(\"Hello\")    // true\nBoolean(0)          // false\n!0                  // true\n!!0                 // false\nBoolean(null)       // false\nBoolean(NaN)        // false\nBoolean(undefined)  // false\nBoolean(\"\")         // false\n```\n\n### Функции\n\n```js\nfunction sum (param1, param2) {\n    console.log(param1*param2)\n}\n\nsum(2,2) // 4\n\nfunction getRandomInt(min, max) {\n    return Math.floor(Math.random() * (max - min + 1)) + min\n}\n\ngetRandomInt(1,100) // Например, 44\n```\n\n### Условия\n\n```js\nfunction functionName (paramName) {\n    if (paramName === 0) {\n        console.log(`${paramName} равно 0`)\n    }\n    else if (paramName \u003c 10) {\n        console.log(`${paramName} меньше 10`)\n    }\n    else if (paramName \u003e= 10) {\n        console.log(`${paramName} больше или равно 10`)\n    }\n    else {\n        console.log(`Переданное значение - ${paramName} - не подходит под заданные условия`)\n    }\n}\n\nfunctionName(0)       // 0 равно 0\nfunctionName(5)       // 5 меньше 10\nfunctionName(15)      // 15 больше или равно 10\nfunctionName('test')  // Переданное значение - test - не подходит под заданные условия\n```\n\nОднострочный формат условия `?:`, который подходит для использования в теле переменной\n\n```js\nlet input = 1\ninput === 1 ? true : false // true\ninput = 2\ninput === 1 ? true : false // false\n```\n\nПроверить одно значение сразу на большое количество условий с помощью конструкции `switch`\n\n```js\nfunction getDayOfWeek(day) {\n    switch (day) {\n        case 1:\n            return 'Понедельник'\n        case 2:\n            return 'Вторник'\n        case 3:\n            return 'Среда'\n        case 4:\n            return 'Четверг'\n        case 5:\n            return 'Пятница'\n        case 6:\n            return 'Суббота'\n        case 7:\n            return 'Воскресенье'\n        default:\n            return 'Неправильно задан параметр'\n    }\n}\n\nconsole.log(getDayOfWeek(1)) // Понедельник\nconsole.log(getDayOfWeek(5)) // Пятница\nconsole.log(getDayOfWeek(7)) // Воскресенье\nconsole.log(getDayOfWeek(8)) // Неправильно задан параметр\n\n```\n\n### Обработка ошибок\n\n```js\nfunction errorTest(a, b) {\n    // Блок кода, который будет выполняется до тех пор, пока не возникнет ошибка\n    try {\n        if (b === 0) {\n            throw new Error(\"на ноль делить нельзя\")\n        }\n        console.log(a / b) // выполняется, если ошибок нет\n    }\n    // Блок кода, который будет выполнен, если в блоке try возникнет ошибка\n    catch (error) {\n        console.log(`Ошибка: ${error.message}`) // Обработка ошибки\n    }\n    // Блок кода, который выполняется в любом случае\n    finally {\n        console.log(\"Блок finally выполняется всегда\") // Всегда выполняется\n    }\n}\n\nerrorTest(10, 2) \n// 5\n// Блок finally выполняется всегда\n\nerrorTest(10, 0)\n// Ошибка: на ноль делить нельзя\n// Блок finally выполняется всегда\n```\n\n### Массивы\n\nКлассический массив и его методы.\n\n```js\nconst array = [3, 2, 'string']\nArray.isArray(array) // Проверка, является ли переменная массивом (true)\narray[2] = 1 // Изменить содержимое элемента в массиве по индексу\narray.sort() // сортировка по умолчанию: [ 1, 2, 3 ]\narray.reverse() // Поменять порядок следования: [ 3, 2, 1 ]\narray[0] + array[1] + array[2] // 6\narray[3] // undefined (не определено)\narray[3] = 4 // Добавить новый элемент в массив по индексу\narray.push(5) // Добавить новый элемент с конца\narray[4] // 5\narray.slice(3,5) // Вывести содержимое массива с 4-го по 5-й индекс: [ 4, 5 ]\narray.unshift(0) // Добавить элемент(ы) (через запятую) в начало массива\narray.shift() // Удалить первый элемент из массива\narray.pop() // Удалить последний элемент из массива\narray[array.length-1] // Вывести содержимое последнего элемента в массиве\narray.indexOf(1) // Выводит индекс первого вхождения элемента в массив, или -1, если элемент не найден\n```\n\nВложенный массив, а также методы фильтрации и объединения:\n\n```js\nconst data = [\n    { id: 1, name: 'red' },\n    { id: 2, name: 'blue' },\n]\n\ndata.push({id: 3, name: 'green'}) // Добавить новый элемент в массив\n\nconst nameArray = data.map(item =\u003e item.name) // Пересобрать новый массив\n\nconst filterArray = nameArray.filter(item =\u003e item.length \u003e= 4) // отфильтровать содержимое массива по длинне содержимого\n// [ 'blue', 'green' ]\n\n[...nameArray, ...filterArray] // объеденить два массива\n// [ 'red', 'blue', 'green', 'blue', 'green' ]\n\nconst idArray = data.map(item =\u003e item.id)\n// Метод reduce выполняет функцию для каждого элемента массива, чтобы получить одно итоговое значение (сумму)\nidArray.reduce((accumulator, current) =\u003e accumulator + current, 0) // 3\n```\n\n### Объекты\n\nПреобразовать объект в массив и наоборот:\n\n```js\nconst obj = { a: 1, b: 2, c: 3 }\nobj.b // 2\nlet keys = Object.keys(obj)      // [ 'a', 'b', 'c' ]\nlet values = Object.values(obj)  // [ 1, 2, 3 ]\nconst arr = Object.entries(obj)  // [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\narr[1][1] // 2\nObject.fromEntries(arr)          // { a: 1, b: 2, c: 3 }\n```\n\nОбъект представляет из себя список пар (ключ-значение), разделенного запятыми. Используя переменную `const` при объявлении объектов, возможно изменять содержимое дочерних элементов.\n\n```js\nconst box = {\n    height: 8,\n    width: 40,\n    scrollable: true,\n    style: {\n        fg: 'white',\n        bg: 'black'\n    }\n}\n\nbox.height // 8\nbox.style // { fg: 'white', bg: 'black' }\nbox.style.fg // white\n\nbox.style.fg = 'blue'\nbox.style.fg // blue\n```\n\nОбъекты и вложенные массивы `JavaScript` могут содержать дочерние массивы внутри `[]` и вложенные объекты внутри `{}`.\n\n```js\nconst obj = [\n    'JavaScript',\n    2024,\n    [\n        'Express',\n        'Axios',\n    ],\n    {\n        name: 'Alex',\n        age: 29,\n        num: [1, 'string', {}],\n        test: {}\n    }\n]\n```\n\nКонвертация в `JSON`:\n\n```js\nconst jsonString = JSON.stringify(obj)  // Конвертация из объекта JavaScript в JSON\nconst obj = JSON.parse(jsonString)      // Конвертация из JSON в JavaScript\n```\n\nМетоды объекта назначаются через функции\n\n```js\nconst obj = {\n    default: 10,\n    get() {\n        return this.default\n    },\n    plus(num) {\n        if (isNaN(num)) {return}\n        this.default += num\n    },\n    minus(num) {\n        if (isNaN(num)) {return}\n        this.default -= num\n    }\n}\n\nobj.minus(1)\nobj.get() // 9\nobj.plus(2)\nobj.get() // 11\n```\n\nОператор `return` используется для выхода из функции (т.е. последующий код не читается), который возвращает значение указанное после ключевого слова.\n\n### Циклы\n\nПримеры циклов взяты из проекта [multranslate](https://github.com/Lifailon/multranslate), для проверки всех строк в массиве и увеличения количества видимых строк с учетом `autowrap`. Имеется две реальных строки, необходимо узнать количество виртуальных строк с учетом длинны символов в строке. Например, если максимальная длинна одной строки составляет, `36`, то на одну реальную строку в `92` символа приходится дополнительно еще `2` виртуальных. Количество найденных виртуальных строк прибавляется к изначально зафиксированному значению количества всех реальных строк.\n\n```js\n// На входе 2 строки, разделенные символом \\r\nconst text = \"Первая строка\\rВторая очень длинная строка, которое будет превышать максимальное значение символов в строке\"\n\n// Фиксируем текущее максимальное количество строк и длинну символов в строке с учетом размеров окна\nconst maxLines = box.height - 2 // 6\nconst maxChars = box.width - 4  // 36\n\n// Разбиваем текст на массив из строк\nconst bufferLine = text.split('\\r')\n// Забираем реальное количество строк (2)\nlet viewLines = bufferLine.length\n\n// Вывести количество строк в каждой строке массива\nbufferLine.map(item =\u003e item.length) // [ 13, 92 ]\n```\n\nКлассический цикл `for` итерирует числами с типом данных `number` (`int` / `integer`). С каждой интерацией объявленное значение (`let i = 0`) увеличивается на заданное количество (`i++` - на единицу), цикл завершается в случае успешного соблюдения условия (`i \u003c bufferLine.length`).\n\n```js\nfor (let i = 0; i \u003c bufferLine.length; i++) {\n    if (bufferLine[i].length \u003e maxChars) {\n        // Добавляем одну виртуальную строку без учета остатка символов\n        viewLines++\n    }\n}\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 3\n// Уменьшаем значение на 1, для проверки в других циклах\nviewLines--\n\nfor (let i = 0; i \u003c bufferLine.length; i++) {\n    if (bufferLine[i].length \u003e maxChars) {\n        // Добавляем все виртуальные строки, с округлением в меньшую сторону\n        viewLines += Math.floor(bufferLine[1].length / maxChars)\n    }\n}\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 4\nviewLines -= 2\n```\n\nЦикл `for..in` итерирует по индексам массива, с типом данных `string`. Сколько элементов в массиве (`bufferLine.length`), столько и будет индексов (отсчет начинается с нуля).\n\n```js\nfor (let index in bufferLine) {\n    if (bufferLine[Number(index)].length \u003e maxChars) {\n        viewLines += Math.floor(bufferLine[1].length / maxChars)\n    }\n}\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 4\nviewLines -= 2\n```\n\nЦикл `for..of` итерирует по элементам массива, с уникальным типом данных каждого элемента в массиве.\n\n```js\nconst array = [1, 'string', {}]\nfor (let arr of array) {\n    console.log(typeof arr)\n}\n// number\n// string\n// object\n\nfor (let line of bufferLine) {\n    console.log(typeof line)\n    if (line.length \u003e maxChars) {\n        viewLines += Math.floor(bufferLine[1].length / maxChars)\n    }\n}\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 4\nviewLines -= 2\n```\n\nМетод массива `forEach` выполняет указанную функцию для каждого элемента в массиве.\n\n```js\nbufferLine.forEach(line =\u003e {\n    if (line.length \u003e maxChars) {\n        viewLines += Math.floor(bufferLine[1].length / maxChars)\n    }\n})\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 4\nviewLines -= 2\n```\n\nЦикл `while` Выполняет тело цикла `{}` до тех пор, пока условие истинно\n\n```js\nlet i = 0\nwhile (i \u003c bufferLine.length) {\n    if (bufferLine[i].length \u003e maxChars) {\n        viewLines += Math.floor(bufferLine[1].length / maxChars)\n    }\n    i++\n}\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 4\nviewLines -= 2\n```\n\nЦикл `do..while` сначала выполняет тело цикла, а затем проверяет условие, это гарантирует, что интерация будет выполнена как минимум один раз.\n\n```js\ni = 0\ndo {\n    if (bufferLine[i].length \u003e maxChars) {\n        viewLines += Math.floor(bufferLine[1].length / maxChars)\n    }\n    i++\n} while (i \u003c bufferLine.length)\nconsole.log(`${maxLines} ${maxChars} ${viewLines}`) // 6 36 4\n```\n\nОператоры:\n\n- `continue` - прерывает текущую интерацию, для продолжения цикла с следующим значением\n- `break` - прерывает и завершает цикл\n\n```js\nlet arr = [0, 1, 2, 4]\nfor (const value of arr) {\n    console.log(`Начало ${value}-й итерации`)\n    if (value === 1) {\n        console.log('Пропустить оставшуюся часть кода и перейти к следующей итерации')\n        continue\n    } else if (value === 2) {\n        console.log('Полностью выйти из цикла')\n        break\n    }\n    console.log(`Конец ${value}-й итерации`)\n}\n\n// Начало 0-й итерации\n// Конец 0-й итерации\n// Начало 1-й итерации\n// Пропустить оставшуюся часть кода и перейти к следующей итерации\n// Начало 2-й итерации\n// Полностью выйти из цикла\n```\n\n### Асинхронные операции\n\n`Promise` (промис) — это объект, который используется для обработки асинхронных операций, позволяя работать с результатами, когда они станут доступны, не блокируя основной поток выполнения. Он может находиться в одном из трех состояний:\n\n- `Pending` (Ожидание): Операция только отправлена на выполнение или еще выполняется.\n- `Fulfilled` (Выполнен): Операция завершилась успешно.\n- `Rejected` (Отклонен): Операция завершилась с ошибкой.\n\nС помощью ключевых слов `resolve` (разрешить/успех) и `reject` (отклонить/ошибка) производится управление возвращаемым результатом выполнения.\n\n```js\nlet testPromise = new Promise((resolve, reject) =\u003e {\n    if (true) {\n        resolve(\"Операция выполнена успешно\")\n    } else {\n        reject(\"Ошибка выполнения операции\")\n    }\n})\n\ntestPromise.then(result =\u003e console.log(result)).catch(error =\u003e console.error(error))\n```\n\nМетод `then` используется для обработки успешного выполнения промиса (в состоянии `fulfilled`).\n\nМетод `catch` используется для обработки ошибок или отказов промиса (в состоянии `rejected`).\n\n`async` — это ключевое слово, которое делает функцию асинхронной и позволяет использовать `await`, чтобы приостановить выполнение до тех пор, пока все промисы не будут выполнены.\n\n`await` — это ключевое слово, которое используется внутри асинхронной функции (async). Оно заставляет ждать выполнения промиса и возвращает его результат.\n\n```js\n// Импортируем функцию exec из модуля child_process, которая позволяет запускать команды операционной системы\nconst { exec } = require('child_process')\n\n// Основная функция выполнения команды ping в промис\nfunction pingHost(host) {\n    return new Promise((resolve) =\u003e {\n        // Выполняем команду ping для указанного хоста с timeout 50 мс\n        exec(`ping -n 1 -w 50 ${host}`, (error) =\u003e {\n            // Если нет ошибки, значит хост отвечает (alive: true)\n            if (!error) {\n                resolve({ host, alive: true })\n            }\n            // Если есть ошибка, хост не отвечает (alive: false)\n            else {\n                resolve({ host, alive: false })\n            }\n        })\n    })\n}\n\n// Асинхронная функция создания промисов и получения результатов\nasync function pingSubnet(subnet) {\n    // Массив для хранения промисов\n    const promises = []\n    // Генерация и пинг каждого IP-адреса в диапазоне от 1 до 254\n    for (let i = 1; i \u003c= 254; i++) {\n        // Формируем IP-адрес, заменяя последний октет подсети\n        const host = `${subnet.split('.').slice(0,3).join('.')}.${i}`\n        // Добавляем промис в массив для выполнения пинга в фоне и продолжения интерации\n        promises.push(pingHost(host)) // Promise { \u003cpending\u003e }\n    }\n    // Ждем завершения выполнения всех промисов\n    const results = await Promise.all(promises)\n    results.forEach(result =\u003e {\n        if (result.alive) {\n            console.log(`+++ ${result.host}`)\n        } else {\n            console.log(`- ${result.host}`)\n        }\n    })\n}\n\npingSubnet('192.168.3.0')\n```\n\nИспользовать внешнюю библиотеку [ping](https://www.npmjs.com/package/ping): `npm install ping`\n\n```js\nconst ping = require('ping')\n\n// Асинхронная функция отправки команды ping через библиотеку\nasync function pingHost(host) {\n    try {\n        const res = await ping.promise.probe(host, { timeout: 1 })\n        return { host, alive: res.alive }\n    } catch (error) {\n        return { host, alive: false }\n    }\n}\n\n// Функция возврата промисов вручную без async\nfunction pingHost(host) {\n    return ping.promise.probe(host, { timeout: 1 })\n        .then(res =\u003e {\n            return { host, alive: res.alive }\n        })\n        .catch(error =\u003e {\n            return { host, alive: false }\n        })\n}\n\nasync function pingSubnet(subnet) {\n    const promises = []\n    for (let i = 1; i \u003c= 254; i++) {\n        const host = `${subnet.split('.').slice(0,3).join('.')}.${i}`\n        promises.push(pingHost(host))\n    }\n    const results = await Promise.all(promises)\n    results.forEach(result =\u003e {\n        if (result.alive) {\n            console.log(`+++ ${result.host}`)\n        } else {\n            console.log(`- ${result.host}`)\n        }\n    })\n}\n\npingSubnet('192.168.3.0')\n```\n\n`await Promise.all()` - дожидается успешного выполнения всех запросов.\n`await Promise.allSettled()` - дожидается выполнения всех запросов не зависимо от успеха (возвращает статус и результат).\n`await Promise.race()` - дожидается первого успешного выполнения, что бы получить результат от него не зависимо от его успеха.\n\n### Регулярные выражения\n\nПреобразовать строку в массив из букв (`char`).\n\n```js\nlet line = \"javascript\"\nlet arr = Array.from(str) // ['j', 'a', 'v', 'a',  's', 'c', 'r', 'i', 'p', 't']\n```\n\nМетод `split()` используется для преобразования строки в массив.\n\n```js\nline = \"1,2,3,4,5\"              // '1,2,3,4,5'\narr = line.split(\",\")           // [ '1', '2', '3', '4', '5' ]\n```\n\nМетод `join()` используется для объединение массива в строку.\n\n```js\nlet arrSlice = arr.slice(1, 3)  // Срез, выводит содержимое массива с 1 по 3 индекс (два элемента)\narrSlice.join()                 // Собирает массив в строку: '2,3'\narrSlice.join(\" - \")            // '2 - 3'\n```\n\nМетод `match()` используется для поиска совпадений с регулярным выражением в строке. Он возвращает массив с найденными совпадениями или `null`, если совпадений не найдено.\n\n```js\nlet stringForRegex = \"Текст для проверки текста\"\nstringForRegex.match(/текст/)[0]     // Получить содержимое первого совпадения\nstringForRegex.match(/текст/).index  // Возвращает порядковый индекс первого совпадения в тексте (19)\nstringForRegex.match(/текст/i)[0]    // Возвращает только первое совпадение без учета регистра\nstringForRegex.match(/текст/gi)      // Получить массив всех совпадений: [ 'Текст', 'текст' ]\n\nstringForRegex = \"2024-10-25\"\nstringForRegex.match(/(\\d{4})-(\\d{2})-(\\d{2})/) // Группа захвата, которая возвращает полное совпадение, а также значения отдельных групп\n// [ '2024-10-25', '2024', '10', '25', index: 0, input: '25-10-2024', groups: undefined ]\n```\n\nМетод `search()` возвращает только индекс первого совпадения.\n\n```js\n\"Текст для проверки текста\".search('про') // 10\n```\n\nМетод `replace()` заменяет найденные совпадения в строке на другие значения.\n\n```js\nstringForRegex = \"Текст для замены\"\nstringForRegex.replace(/для/, \"после\")              // 'Текст после замены'\nstringForRegex.replace(/^т/i, \"Этот т\")             // 'Этот текст для замены'\nstringForRegex.replace(/$/, \"!\")                    // 'Текст для замены!'\nstringForRegex.replace(/(Текст)/, \"$1 только\")      // 'Текст только для замены'\nstringForRegex.replace(/\\s[а-яА-Я]{3}/, \"\")         // 'Текст замены'\nstringForRegex.replace(/\\s\\p{L}+$/u, \" кириллицы\")  // 'Текст для кириллицы'\n\nstringForRegex = \"Text for regex\"\nstringForRegex.replace(/\\s\\w{3}/, \"\")         // Используется для замены любых латинских букв: 'Text regex'\nstringForRegex.replace(/\\s[a-zA-Z_]{3}/, \"\")  // эквивалент \\w\n\nstringForRegex = \"2024-10-25\"\nstringForRegex = stringForRegex.replace(/(\\d{4})-(\\d{2})-(\\d{2})/,\"$3.$2.$1\") // Поменять порядок через группы захвата: '25.10.2024'\nstringForRegex.replace(/\\d{2}\\./g, \"11.\")   // Заменяет найденные две идущие цифры подряд: '11.11.2024'\nstringForRegex.replace(/\\d{4}/, \"2025\")     // Заменяет четыре идущие цифры подряд: '25.10.2025'\nstringForRegex.replace(/20\\d+/, \"2025\")     // Заменяет 20 и любые идущие за ним цифры: '25.10.2025'\nstringForRegex.replace(/10.+/g, \"11.2025\")  // Заменяет 10 и любое количетво символов идущее за ним: '25.11.2025'\nstringForRegex.replace(/\\d{2,4}/g, \"11\")    // Заменяет найденные цифры следующие в порядке от 2 до 4: ('11.11.11')\nstringForRegex.replace(/[45]/g, \"1\")        // Заменить 4 или 5 на 1: '21.10.2021'\n```\n\n### Математические вычисления\n\n```js\nMath.min(9, 10)        // Получить наименьшее значение двух чисел: 9\nMath.max(9, 10)        // Получить максимальное значение двух чисел: 10\nMath.floor(10 / 3)     // Округлить в меньшую сторону: 3\nMath.ceil(10/3)        // Откруглить в большую сторону: 4\nMath.trunc(4.9)        // Отбрасывание дробной части: 4\nMath.round(4.5)        // Округление до ближайшего целого: 5\nMath.round(4.45)       // Округление до ближайшего целого: 4\nMath.fround(5.05)      // Ближайшее число с плавающей точкой одинарной точности: 5.050000190734863\nMath.random()          // Псевдослучайное число между 0 и 1, например, 0.2309471255442206\nMath.abs(-7)           // Получить абсолютное значение: 7\nMath.sign(-3)          // Определение знака числа (-1, 0, 1): -1\nMath.pow(2, 3)         // Возведение в степень: 8\nMath.sqrt(16)          // Квадратный корень: 4\nMath.cbrt(27)          // Кубический корень: 3\nMath.imul(2, 4)        // Целочисленное 32-битное умножение: 8\nMath.clz32(1)          // Количество ведущих нулей в 32-битном представлении: 31\n```\n\n### Express\n\nСоздаем директорию, инициализируем проект и устанавливаем зависимости\n\n```shell\nmkdir api \u0026\u0026 cd api\nnpm init -y\nnpm install express\n```\n\nСерверная часть `API` сервера в файле `server.js`\n\n```js\nconst express = require('express')\n\nconst web = express()\n\n// Middleware для парсинга JSON данных в теле запроса\nweb.use(express.json())\n\n// Обработка GET запроса с параметрами в пути и заголовками\nweb.get('/user/:id', (req, res) =\u003e {\n    const userId = req.params.id // Получаем параметр id из пути\n    const customHeader = req.headers['custom-header'] // Чтение заголовка custom-header\n    res.json({\n        message: `GET запрос для пользователя с ID ${userId}`,\n        customHeader: customHeader || 'Заголовок отсутствует'\n    })\n})\n\n// Обработка POST запроса с данными в теле запроса и заголовками\nweb.post('/user', (req, res) =\u003e {\n    const { name, age } = req.body // Получаем данные из тела POST запроса\n    const authHeader = req.headers['authorization'] // Чтение содержимого из заголовка `authorization`\n    if (authHeader !== 'Bearer TOKEN') {\n        res.json({\n            message: `Авторизация не пройдена, переданный токен: ${authHeader}`\n        })\n    } else {\n        res.json({\n            name: name || 'Не указано',\n            age: age || 'Не указано',\n        })\n    }\n})\n\n// Запуск сервера на порту 3000\nconst PORT = 3000\nweb.listen(PORT, () =\u003e {\n    console.log(`Сервер запущен на http://localhost:${PORT}`)\n})\n```\n\nЗапуск сервера\n\n```shell\nnode server.js\n```\n\n### Axios\n\nКлиентская часть для работы с `API`\n\n```shell\nnpm install axios\n```\n\nПример `GET` запроса\n\n```js\nconst axios = require('axios')\n\n// URL сервера\nconst url = 'http://localhost:3000'\n\n// Пример GET запроса с параметром id в пути и кастомным заголовком\nasync function getUser(userId, Header) {\n    try {\n        const response = await axios.get(`${url}/user/${userId}`, {\n            headers: {\n                'custom-header': Header\n            }\n        })\n        console.log('GET Ответ:', response.data)\n    } catch (error) {\n        console.error('Ошибка GET запроса:', error.message)\n    }\n}\n\nawait getUser(1, 'Value')\n// GET Ответ: {\n//   message: 'GET запрос для пользователя с ID 1',\n//   customHeader: 'Value'\n// }\n```\n\nПример `POST` запроса\n\n```js\n// Пример POST запроса с телом и заголовком авторизации\nasync function createUser(key, name, age) {\n    try {\n        const response = await axios.post(`${url}/user`, {\n            name: name,\n            age: age\n        }, {\n            headers: {\n                'Authorization': `Bearer ${key}`\n            }\n        })\n        console.log('POST Ответ:', response.data)\n    } catch (error) {\n        console.error('Ошибка POST запроса:', error.message)\n    }\n}\n\nawait createUser('KEY', 'Alex', 29)\n// POST Ответ: { message: 'Авторизация не пройдена, переданный токен: Bearer KEY' }\n\nawait createUser('TOKEN', 'Alex', 29)\n// POST Ответ: { name: 'Alex', age: 29 }\n```\n\n### Fetch\n\n```js\nasync function fetchData(url) {\n    try {\n        // Отправляем GET-запрос на указанный URL\n        const response = await fetch(url)\n        // Проверяем, что ответ успешен\n        if (!response.ok) {\n            throw new Error(`Error Status: ${response.status}`)\n        }\n        // Получаем и выводим данные в формате JSON\n        const data = await response.json()\n        return data\n    }\n    // Обрабатываем ошибки\n    catch (error) {\n        console.error('Error:', error)\n    }\n}\n\nconst result = await fetchData('https://jsonplaceholder.typicode.com/todos/1')\nresult // { userId: 1, id: 1, title: 'delectus aut autem', completed: false }\nJSON.stringify(result) // '{\"userId\":1,\"id\":1,\"title\":\"delectus aut autem\",\"completed\":false}'\n```\n\n### Cheerio\n\nCheerio - это библиотека для работы с `HTML` и `XML` в `Node.js`\n\n```shell\nnpm install axios cheerio https-proxy-agent iconv-lite\n```\n\nПодключаем библиотеки и получаем содержимое страницы с помощью `Axios` через `Proxy`\n\n```js\nconst axios    = require('axios')\nconst cheerio  = require('cheerio')\nconst proxy    = require('https-proxy-agent')\nconst iconv    = require('iconv-lite')\n\n// Имя агента в заголовке запросов (вместо axios)\nconst headers = {\n    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0 Win64 x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'\n}\n\nconst proxyAddress = '192.168.3.100'\nconst proxyPort = 9090\nconst username = 'test'\nconst password = 'test'\n\n// Создание экземпляра Axios с использованием конфигурации Proxy\nconst createAxiosProxy = () =\u003e {\n    const config = {}\n    config.httpsAgent = new proxy.HttpsProxyAgent(`http://${username}:${password}@${proxyAddress}:${proxyPort}`)\n    return axios.create(config)\n}\nconst axiosProxy = createAxiosProxy()\n\nconst url = \"https://rutor.info\"\n\n// Отправляем запрос\nconst response = await axiosProxy.get(url, {\n    responseType: 'arraybuffer',\n    headers: headers\n})\n\n// Декодируем ответ\nhtml = iconv.decode(response.data, 'utf8')\n```\n\nВытаскиваем данные с помощью `Cheerio`\n\n```js\nconst data = cheerio.load(html)\n\n// Обращаемся к элементу div (не обязательно указывать название элемента) с id=\"ws\" \u003e div с id=\"index\" \u003e элемент \"tbody\" (таблица) \u003e элемент \"tr\" (строки)\ndata('div#ws #index tbody tr').length // 171\n// Исключить из вывода строку с class=\"backgr\" (загловки столбцов)\ndata('#ws #index tbody tr').not('.backgr').length // 170\n\n// Получить содержимое первого элемента \"tr\" в формате HTML, строки или текста без тегов\ndata('#ws #index tbody tr').not('.backgr').eq(0).html()\ndata('#ws #index tbody tr').not('.backgr').eq(0).toString()\ndata('#ws #index tbody tr').not('.backgr').eq(0).text()\n\n// Получить содержимое элемента по частичному совпадению\ndata('#ws #index tbody tr').not('.backgr').find('td:contains(\"слово\")').text().replace('\\n','').trim()\n// 'Мужское слово (2024) WEB-DLRip'\n\n// Получить содержимое второго элемента по индексу в строке (столбцe)\ndata('#ws #index tbody tr').not('.backgr').eq(0).find('td').eq(1).text().replace('\\n','').trim()\n// 'Launcher for Zapret [v 1.3] (2024) PC | Portable'\n\n// Получить содержимое атрибута \"href\" из элемента с классом \"downgif\"\ndata('#ws #index tbody tr').not('.backgr').eq(0).find('td a.downgif').attr('href')\n// '//d.rutor.info/download/1008549'\n\n// Получить содержимое атрибута \"href\" из второго элемента \"a\" в элементе \"td\"\ndata('#ws #index tbody tr').not('.backgr').eq(0).find('td a:nth-child(2)').attr('href')\n// 'magnet:?xt=urn:btih:f1ca88b9421b243b6cb3d4da90e8fe133f381817\u0026dn=rutor.info\u0026tr=udp://opentor.net:6969\u0026tr=http://retracker.local/announce'\n\n// Фильтруем все элементы по частичному совпадению\ndata('#ws #index tbody tr').not('.backgr').filter((index, element) =\u003e {\n    // Проверяем, содержит ли текущая строка \"tr\" слово \"Крит\" в одном из столбцов \"td\"\n    return data(element).find('td:contains(\"Крит\")').length \u003e 0\n}).map((index, element) =\u003e {\n    // Если слово найдено, извлекаем текст всех \"td\" в этой строке с помощью map()\n    return data(element).find('td').map((index, element) =\u003e data(element).text()).get().join(' | ').replace('\\n','')\n}).get()\n\n// [\n//   '29 Окт 24 | Критик / The Critic (2023) WEB-DLRip 1080p от ExKinoRay | P  | 6.10 GB |  1  4',\n//   '28 Окт 24 | Критик / The Critic (2023) WEB-DLRip | P  | 1.46 GB |  58  22',\n//   '28 Окт 24 | Критик / The Critic (2023) WEB-DLRip-AVC от DoMiNo \u0026 селезень | P  | 1.46 GB |  64  19',\n//   '28 Окт 24 | Критик / The Critic (2023) WEB-DL 1080p | P | RGB  | 1 | 5.63 GB |  115  54'\n// ]\n\nconst torrents = []\n\n// Собираем объект из всех элементов\ndata('#ws #index tbody tr').not('.backgr').each((index, element) =\u003e {\n    const row = data(element)\n    const torrent = {\n        'Date': row.find('td').eq(0).text().trim(),\n        'Name': row.find('td').eq(1).find('a').last().text().trim(),\n        'Link': 'https://rutor.info' + row.find('td').eq(1).find('a[href^=\"/torrent\"]').attr('href'),\n        'DownloadLink': 'https://' + row.find('td').eq(1).find('a.downgif').attr('href'),\n        'Magnet': row.find('td').eq(1).find('a[href^=\"magnet:\"]').attr('href')\n    }\n    torrents.push(torrent)\n})\n\n// Конвертируем объект в формат JSON\nconsole.log(JSON.stringify(torrents, null, 2))\n\n// [\n//   {\n//     \"Date\": \"29 Окт 24\",\n//     \"Name\": \"Launcher for Zapret [v 1.3] (2024) PC | Portable\",\n//     \"Link\": \"https://rutor.info/torrent/1008549/launcher-for-zapret-v-1.3-2024-pc-portable\",\n//     \"DownloadLink\": \"https:////d.rutor.info/download/1008549\",\n//     \"Magnet\": \"magnet:?xt=urn:btih:f1ca88b9421b243b6cb3d4da90e8fe133f381817\u0026dn=rutor.info\u0026tr=udp://opentor.net:6969\u0026tr=http://retracker.local/announce\"\n//   },\n//   ...\n// ]\n```\n\n### Puppeteer\n\nPuppeteer — это библиотека, которая предоставляет `API` для автоматизации любых действий в браузерах **Google Chrome** и **Mozilla Firefox** через протокол `Chrome DevTools` и `WebDriver BiDi`.\n\n```shell\nmkdir api \u0026\u0026 cd api \u0026\u0026 npm init -y \u0026\u0026 npm install puppeteer\n```\n\nПример получения списка файлов раздачи с сайта [RuTor](https://rutor.info).\n\n```js\nconst puppeteer = require('puppeteer')\n// Запускаем браузер и открываем новую пустую страницу \nconst browser = await puppeteer.launch({\n    headless: true // Отключить отображение браузера (параметр по умолчанию)\n})\nconst page = await browser.newPage()\n// Открываем страницу с ожиданием загрузки 60 сек\nconst query = 721221\nawait page.goto(`https://rutor.info/torrent/${query}`, {\n    timeout: 60000,\n    waitUntil: 'domcontentloaded' // ожидать только полной загрузки DOM (не ждать загрузки внешних ресурсов, таких как изображения, стили и скрипты)\n})\nawait page.evaluate(() =\u003e {\n    // Находим кнопку по JavaScript пути и нажимаем на нее\n    // document.querySelector(\"#details \u003e tbody \u003e tr:nth-child(11) \u003e td.header \u003e span\").click()\n    // document.querySelector(\"#details \u003e tbody \u003e tr:nth-child(12) \u003e td.header \u003e span\").click()\n    // Находим все кпноки которые содержат class=\"button\"\n    const buttons = document.querySelectorAll('span.button')\n    // Проходимся по найденным кнопкам\n    buttons.forEach(button =\u003e {\n        // Проверяем, содержит ли кнопка текст \"Файлы\" и нажимаем на нее\n        if (button.textContent.includes('Файлы')) {\n            button.click()\n        }\n    })\n})\n// Дождаться загрузки результатов\n// const elementHandle = await page.waitForSelector('#files')\n// Ищем элемент с идентификатором #files и проверяем, что элемент существует его содержимое не содержит текст загрузки\nawait page.waitForFunction(() =\u003e {\n    const element = document.querySelector('#files')\n    return element \u0026\u0026 !element.textContent.includes(\"Происходит загрузка списка файлов...\")\n}, {\n    timeout: 30000, // Ожидать результат 30 секунд\n    polling: 50   // Проверка каждые 50мс (по умолчанию 100мс)\n})\n// Забираем результат после успешной проверки\nconst elementContent = await page.evaluate(() =\u003e {\n    const element = document.querySelector('#files')\n    return element ? element.textContent : null\n})\n// Закрываем браузер\nawait browser.close()\n// Разбиваем полученные результаты на массив из строк (split) исключая первую строку (slince)\nconst lines = elementContent.trim().split('\\n').slice(1)\n// Регулярное выражение для разбиения строки на название и размер\nconst regex = /^(.+?)([\\d.]+\\s*\\S+)\\s+\\((\\d+)\\)$/\nconst torrents = []\nfor (const line of lines) {\n    const match = line.match(regex)\n    const torrent = {\n        'Name': match[1],\n        'Size': match[2]\n    }\n    torrents.push(torrent)\n}\nconsole.log(JSON.stringify(torrents, null, 2))\n```\n\nПример создания `API` для получения результатов проверки скорости интернета в формате `JSON` через [Ookla SpeedTest](https://www.speedtest.net).\n\n```js\nconst puppeteer = require('puppeteer')\nconst browser = await puppeteer.launch({\n    headless: false\n})\nconst page = await browser.newPage()\nawait page.goto(`https://www.speedtest.net`, {\n    waitUntil: 'domcontentloaded'\n})\n// Дождаться, когда кнопка \"Go\" станет доступной\nawait page.waitForSelector('span[data-testid=\"start-button\"]')\n// Возвращаем массив всех элементов span на странице с их текстом\nawait page.evaluate(() =\u003e {\n    return Array.from(document.querySelectorAll('span')).map(elemet =\u003e ({\n        Text: elemet.innerText, // Текст, отображаемый внутри элемента\n        Content: elemet.textContent, // Весь текст внутри элемента, включая скрытые части\n        // HTML: elemet.innerHTML, // HTML-код, который находится внутри элемента\n        // AllHTML: elemet.outerHTML , // Весь HTML-код, который находится внутри элемента\n        id: elemet.id, // Уникальный идентификатор элемента (#)\n        className: elemet.className,\n        tagName: elemet.tagName // Имя тега элемента (например, SPAN)\n    }))\n})\n// Находим и нажимаем на кнопку\nawait page.evaluate(() =\u003e {\n    const buttons = document.querySelectorAll('span')\n    buttons.forEach(button =\u003e {\n        if (button.textContent.includes('Go') || button.innerText.includes('GO')) {\n            button.click()\n        }\n    })\n})\n// Функция для получения результата\nasync function checkResult () {\n    return await page.evaluate(() =\u003e {\n        const element = document.querySelector('div.result-data a')\n        return element ? element.getAttribute('href') : null\n    })\n}\n// Цикл для проверки получения результата\nlet resultUrl = '#'\n// Проверяем, что результат содержит в начале строки 'http'\nwhile (!resultUrl.startsWith('http')) {\n    resultUrl = await checkResult()\n}\nawait browser.close()\n\n// Считываем данные из полученного url с помощью Fetch\nconst result = await fetch(resultUrl)\nconst resultHTML = await result.text()\n// Вытаскиваем JSON из HTML страницы\nconst resultJSON = resultHTML.split('window.OOKLA')[3].replace('.INIT_DATA  = ','').replace(';\\n','')\nconst resultObj = JSON.parse(resultJSON)\n\nresultObj.result.id // 16947429430\nresultObj.result.download // 7169 (7.17)\nresultObj.result.upload // 4939 (4.94)\nresultObj.result.idle_latency // 171 (ping)\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLifailon%2Fnode.js-cheat-sheet-ru","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLifailon%2Fnode.js-cheat-sheet-ru","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLifailon%2Fnode.js-cheat-sheet-ru/lists"}