{"id":338044,"date":"2022-09-07T09:00:50","date_gmt":"2022-09-07T09:00:50","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=338044"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=338044","title":{"rendered":"<span>TypeScript: \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 Radash<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/um\/fe\/t_\/umfet_kngorlggfmgokzowwtsuu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/um\/fe\/t_\/umfet_kngorlggfmgokzowwtsuu.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/radash-docs.vercel.app\/docs\/getting-started\">Radash<\/a> \u2014 \u044d\u0442\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 <a href=\"https:\/\/lodash.com\/\">Lodash<\/a>, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u043d\u0430\u0431\u043e\u0440 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 (\u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439), \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 <a href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a>. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/rayepps\/radash\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0441\u0435\u0431\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f\u044b.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0432\u043e\u0442 <a href=\"https:\/\/my-js.org\/docs\/other\/snippets-js\">\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0441\u043d\u0438\u043f\u043f\u0435\u0442\u043e\u0432 JavaScript<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0447\u0435\u0433\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043f\u0440\u043e\u0449\u0435.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"generacii-i-izvlechenie-proizvolnyh-znacheniy\">\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/h2>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0446\u0435\u043b\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const randomInt = (min: number, max: number) => ~~(Math.random() * (max - min + 1) + min);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const randomInt = randomInt(1, 10); console.log(randomInt); \/\/ 6<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043b\u0430\u0441\u0441\u0438\u043a\u0430.<\/p>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const draw = &lt;T>(arr: T[]): T | null => {   \/\/ \u0434\u043b\u0438\u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430   const len = arr.length;   \/\/ \u0435\u0441\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u044b\u043c   if (len === 0) {     return null;   }   \/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0435 \u0446\u0435\u043b\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0442 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430   const i = random(0, len - 1);   \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442   return arr[i]; };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const arr = [1, 2, 3, 4, 5]; const randomItem = draw(arr); console.log(randomItem); \/\/ 4<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043c\u043e\u0436\u043d\u043e \u043c\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const draw = &lt;T>(arr: T[], mutate?: boolean): T | null => {   const len = arr.length;   if (len === 0) {     return null;   }   const i = random(0, len - 1);   \/\/ \u043c\u0435\u0442\u043e\u0434 `splice` \u043c\u0443\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432   return mutate ? arr.splice(i, 1)[0] : arr[i]; };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const arr = [1, 2, 3, 4, 5]; const randomItems = []; while (arr.length) {   const randomItem = draw(arr, true);   randomItems.push(randomItem); } \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 console.log(randomItems); \/\/ [2, 5, 1, 4, 3]<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0441 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const shuffle = &lt;T>(arr: T[]): T[] => {   return arr     \/\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 `random` \u0438 `value`     .map((a) => ({ random: Math.random(), value: a }))     \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u043e \u043f\u043e\u043b\u044e `random`     .sort((a, b) => a.random - b.random)     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     .map((a) => a.value); };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const arr = [1, 2, 3, 4, 5]; const randomItems = shuffle(arr); console.log(randomItems); \/\/ [4, 2, 5, 1, 3]<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0430\u044f, \u043d\u043e <a href=\"https:\/\/stackoverflow.com\/questions\/2450954\/how-to-randomize-shuffle-a-javascript-array\">\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f<\/a> \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const shuffle = &lt;T>(arr: T[]): T[] =>   arr.slice().sort(() => Math.random() - 0.5);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A2%D0%B0%D1%81%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A4%D0%B8%D1%88%D0%B5%D1%80%D0%B0_%E2%80%94_%D0%99%D0%B5%D1%82%D1%81%D0%B0\">\u0422\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u0424\u0438\u0448\u0435\u0440\u0430-\u0419\u0435\u0442\u0441\u0430<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const shuffle = &lt;T>(arr: T[]): T[] => {   let len = arr.length;   while (len) {     const i = ~~(Math.random() * len--);     [arr[len], arr[i]] = [arr[i], arr[len]];   }   return arr; };<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const uid = (length: number, symbols: string = \"\") => {   \/\/ \u0441\u0438\u043c\u0432\u043e\u043b\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a\u0438   const chars =     \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" + symbols;   \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442   let _uid = \"\";   for (let i = 1; i &lt;= length; i++) {     \/\/ \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b     const i = random(0, chars.length - 1);     \/\/ \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443     _uid += characters[i];   }   \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442   return _uid; };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const randomStr = uid(10); console.log(randomStr); \/\/ xQZc1hzSqa<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ 10-11 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \/\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0447\u0438\u0441\u043b\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0435 2 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 - `0.` const uid = () => Math.random().toString(36).slice(2);<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0442\u0430\u043a\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438, \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 <code>DOM-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432<\/code>, \u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e <a href=\"https:\/\/stackoverflow.com\/questions\/70579\/what-are-valid-values-for-the-id-attribute-in-html\"><code>id<\/code> \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u0447\u0438\u0441\u043b\u0430<\/a>. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u043a\u0430\u043a-\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e <a href=\"https:\/\/stackoverflow.com\/questions\/3434278\/do-dom-tree-elements-with-ids-become-global-properties\"><code>\u0442\u0430\u043a\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 window<\/code><\/a>. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u043d\u0430 \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0431\u0443\u043a\u0432\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>x<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0431\u0443\u043a\u0432\u043e\u0439 `x` const uid = () => Math.random().toString(36).slice(2).replace(\/\\d\/, \"x\");<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0432\u0438\u0433\u0430\u0435\u043c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"rabota-s-massivami-i-obektami\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438 \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438<\/h2>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f-\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function* range(   \/\/ \u043d\u0430\u0447\u0430\u043b\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430   start: number,   \/\/  \u043a\u043e\u043d\u0435\u0446 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430   end: number,   \/\/ \u0448\u0430\u0433   step: number = 1 ): Generator&lt;number> {   for (let i = start; i &lt;= end; i += step) {     yield i;     \/\/ \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440, \u0435\u0441\u043b\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043b\u044e\u0441 \u0448\u0430\u0433 \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u0446\u0430 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430     if (i + step > end) break;   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const numsRange = range(1, 10, 2); console.log(numsRange.next().value);  \/\/ 1 console.log(numsRange.next().value);  \/\/ 3 console.log(...numsRange);            \/\/ 5 7 9<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 const list = (start: number, end: number, step: number = 1): number[] =>   Array.from(range(start, end, step));<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const arrWithNumsRange = list(1, 10, 2); console.log(arrWithNumsRange); \/\/ [1, 3, 5, 7, 9]<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441 \u0447\u0438\u0441\u043b\u0430\u043c\u0438 \u0434\u0432\u043e\u0439\u043d\u043e\u0439 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const list = (   start: number = 0,   stop: number = 1,   step: number = 0.1,   \/\/ \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u043e\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f   precision: number = 1 ) =>   Array.from({ length: (stop - start) \/ step + 1 }, (_, i) =>     \/\/ \u043c\u0435\u0442\u043e\u0434 `toFixed` \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443     \/\/ \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0435 \u0432 \u0447\u0438\u0441\u043b\u043e     Number((start + i * step).toFixed(precision))   );<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const arrWithNumsRange = list(); console.log(arrWithNumsRange); \/\/ [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043d\u0430 \u0447\u0430\u0441\u0442\u0438<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const chunk = &lt;T>(arr: T[], size: number = 2): T[][] => {   \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u044b \u043c\u0430\u0441\u0441\u0438\u0432\u0430   \/\/ \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441 \u043e\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u0435\u043c \u0432 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443   const chunks = Math.ceil(arr.length \/ size);   \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0434\u043b\u0438\u043d\u043e\u0439, \u0440\u0430\u0432\u043d\u043e\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0447\u0430\u0441\u0442\u0435\u0439   \/\/ \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043a\u043e\u043f\u0438\u0438 \u0447\u0430\u0441\u0442\u0435\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430   return Array.from({ length: chunks }, (_, i) =>     arr.slice(i * size, i * size + size)   ); };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const arr = [1, 2, 3, 4, 5]; const chunked = chunk(arr, 2); console.log(chunked); \/\/ [ [1, 2], [3, 4], [5] ]<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const objectify = &lt;T, Key extends string | number | symbol, Value = T>(   arr: T[],   \/\/ \u0433\u0435\u0442\u0442\u0435\u0440 \u043a\u043b\u044e\u0447\u0435\u0439   getKey: (i: T) => Key,   \/\/ \u0433\u0435\u0442\u0442\u0435\u0440 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 - \u043e\u0431\u044a\u0435\u043a\u0442   getValue: (i: T) => Value = (i) => i as unknown as Value ): Record&lt;Key, Value> =>   arr.reduce(     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442     (acc, item) => ({       ...acc,       \/\/ \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e       [getKey(item)]: getValue(item),     }),     {} as Record&lt;Key, Value>   );<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const usersArr = [   { name: \"Alice\", age: 23 },   { name: \"Bob\", age: 32 }, ]; \/\/ \u0433\u0435\u0442\u0442\u0435\u0440 \u043a\u043b\u044e\u0447\u0435\u0439 const usersObj = objectify(usersArr, (u) => u.name); console.log(usersObj); \/*   {     Alice: { name: 'Alice', age: 23 },     Bob: { name: 'Bob', age: 32 }   }  *\/  \/\/ \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u043a\u043b\u044e\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 const usersObj2 = objectify(   usersArr,   (u) => u.name,   (u) => u.age ); console.log(usersObj2); \/\/ { Alice: 23, Bob: 32 }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const listify = &lt;TVal, TKey extends string | number | symbol, KRes>(   obj: Record&lt;TKey, TVal>,   \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f-\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c   toItem: (key: TKey, val: TVal) => KRes ) => {   const entries = Object.entries(obj);    if (entries.length === 0) return [];    return entries.reduce((acc, entry) => {     return [...acc, toItem(entry[0] as TKey, entry[1] as TVal)];   }, [] as KRes[]); };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const usersObj = {   alice: {     age: 23,   },   bob: {     age: 32,   }, }; \/\/ `key` - \u043a\u043b\u044e\u0447\/\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043d\u0438\u0436\u043d\u0435\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435 \/\/ `val` - \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: `{ age: number }` const usersArr = listify(usersObj, (key, val) => ({   \/\/ \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442   ...val,   \/\/ \"\u043a\u0430\u043f\u0438\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\" \u0438\u043c\u044f   name: key[0].toUpperCase() + key.slice(1), })); console.log(usersArr); \/*   [     { age: 23, name: \"Alice\" },     { age: 32, name: \"Bob\" }   ] *\/<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0435-\u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"rabota-s-funkciyami\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438<\/h2>\n<p>  <\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const partial =   \/\/ (\u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b)   (fn: Function, ...args: any[]) =>   \/\/ (\u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b)   (...rest: any[]) =>     fn(...args, ...rest);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0441\u043a\u0438\u0434\u043a\u0430 const discount = 0.1; \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0446\u0435\u043d\u044b \u0441\u043e \u0441\u043a\u0438\u0434\u043a\u043e\u0439, \u0440\u0430\u0432\u043d\u043e\u0439 10% \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u043e\u0432\u0430\u0440\u0430 const getPriceWithDiscount = partial(   \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0446\u0435\u043d\u044b \u0441\u043e \u0441\u043a\u0438\u0434\u043a\u043e\u0439   (d: number, p: number) => p - p * d,   \/\/ \u0441\u043a\u0438\u0434\u043a\u0430   discount ); \/\/ \u0446\u0435\u043d\u0430 const price = 100; \/\/ \u0446\u0435\u043d\u0430 \u0441\u043e \u0441\u043a\u0438\u0434\u043a\u043e\u0439 const priceWithDiscount = getPriceWithDiscount(price); console.log(priceWithDiscount); \/\/ 90<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 (\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Proxy\">Proxy<\/a>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const proxied = &lt;T, K>(   \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443   handler: (prop: T) => K ): Record&lt;string, K> =>   new Proxy(     {},     {       get: (_, prop: any) => handler(prop),     }   );<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const person = {   firstName: \"Harry\",   lastName: \"Heman\", };  const proxiedPerson = proxied((prop: keyof typeof person) =>   \/\/ \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440   person[prop].toUpperCase() );  console.log(proxiedPerson.firstName); \/\/ HARRY<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043c\u0435\u043c\u043e\u0438\u0437\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u0435\u043c\u043e\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c (memoize) \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u044b\u0437\u043e\u0432\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0442\u0438\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u0435\u043c\u043e\u0438\u0437\u0430\u0446\u0438\u0438 type Func&lt;TArgs = any, KReturn = any | void> = (...args: TArgs[]) => KReturn; \/\/ \u0442\u0438\u043f \u043a\u0435\u0448\u0430 - \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 `exp` \u0438 `value` type Cache&lt;T> = Record&lt;string, { exp: number; value: T }>;  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f const memoize = &lt;T>(   \/\/ \u043a\u0435\u0448 - \u043e\u0431\u044a\u0435\u043a\u0442   cache: Cache&lt;T>,   \/\/ \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f   fn: Func&lt;any, T>,   \/\/ \u0433\u0435\u0442\u0442\u0435\u0440 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u0435\u0448\u0443   keyFunc: Func&lt;string> | null,   \/\/ \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043a\u0435\u0448\u0430 - \u0441\u0440\u043e\u043a, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0435\u0448 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c   ttl: number ) => {   return function callWithMemo(...args: any): T {     \/\/ \u043a\u043b\u044e\u0447 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u0435\u0448\u0443     const key = keyFunc ? keyFunc(...args) : JSON.stringify({ args });     \/\/ \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u0435\u0448\u0435?     const existing = cache[key];     \/\/ \u0435\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f     if (existing !== undefined) {       \/\/ \u0438 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043a\u0435\u0448\u0430 \u043d\u0435 \u0438\u0441\u0442\u0435\u043a\u043b\u043e       if (existing.exp > new Date().getTime()) {         \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         return existing.value;       }     }     \/\/ \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     const result = fn(...args);     \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u0435\u0448     cache[key] = {       exp: new Date().getTime() + ttl,       value: result,     };     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     return result;   }; };  const memo = &lt;TFunc extends Function>(   \/\/ \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f   fn: TFunc,   \/\/ \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438   {     \/\/ \u0433\u0435\u0442\u0442\u0435\u0440 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u0435\u0448\u0443     key = null,     \/\/ \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043a\u0435\u0448\u0430     ttl = 300,   }: {     key?: Func&lt;any, string> | null;     ttl?: number;   } = {} ) => memoize({}, fn as any, key, ttl) as any as TFunc;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const factorial = (n: number): number => (n &lt;= 1 ? 1 : n * factorial(n - 1)); const memoizedFactorial = memo(factorial);  console.time(\"t1\"); \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u043c\u043e\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 - \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f memoizedFactorial(150); console.timeEnd(\"t1\"); \/\/ 0.10...  console.time(\"t2\"); \/\/ \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u043c\u043e\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0442\u0435\u043c \u0436\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c - \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u0435\u0448\u0430 memoizedFactorial(150); console.timeEnd(\"t2\"); \/\/ 0.01...<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0414\u0435\u0431\u0430\u0443\u043d\u0441\u0438\u043d\u0433 \u0438 \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438: \u0434\u0435\u0431\u0430\u0443\u043d\u0441\u0438\u043d\u0433 (debouncing) \u2014 \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0435\u0435 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0430 \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433 (throttling) \u2014 \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0435\u0435 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 (\u043e\u0431\u044b\u0447\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0438\u043e\u0434\u0430).<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0434\u0435\u0431\u0430\u0443\u043d\u0441\u0438\u043d\u0433\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043b\u043b\u0431\u0435\u043a, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \/\/ \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 \u043c\u0441 export const debounce = (fn: Function, ms: number) => {   let timer: any = null;   const debounced = (...args: any[]) => {     \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     clearTimeout(timer);     timer = setTimeout(() => {       \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043b\u043b\u0431\u0435\u043a       fn(...args);       \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440       clearTimeout(timer);     }, ms);   };   return debounced; };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;p id=\"par\">0&lt;\/p> &lt;button id=\"btn\">click&lt;\/button><\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0430\u0440\u0430\u0433\u0440\u0430\u0444 const par = document.getElementById(\"par\"); \/\/ \u0441\u0447\u0435\u0442\u0447\u0438\u043a let clicks = 0; \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043b\u0438\u043a\u0430 const onClick = () => {   \/\/ \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430   clicks += 1;   \/\/ \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0430\u0440\u0430\u0433\u0440\u0430\u0444\u0430   (par as HTMLParagraphElement).textContent = clicks.toString(); }; \/\/ \u0434\u0435\u0431\u0430\u0443\u043d\u0441\u0438\u043d\u0433 const debouncedOnClick = debounce(onClick, 1000); \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 const btn = document.getElementById(\"btn\"); \/\/ \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a (btn as HTMLButtonElement).onclick = throttledOnClick;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u044b \u0440\u0430\u0437 \u043c\u044b \u043d\u0435 \u043d\u0430\u0436\u0430\u043b\u0438 \u043a\u043d\u043e\u043f\u043a\u0443, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 1 \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 1 \u0441\u0435\u043a \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u044f. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u0435\u0431\u0430\u0443\u043d\u0441\u0438\u043d\u0433 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u0430\u043a <code>scroll<\/code> \u0438 <code>mousemove<\/code> (\u0438\u043b\u0438 <code>touchmove<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0422\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043b\u043b\u0431\u0435\u043a, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e  \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \/\/ \u0438 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0432 \u043c\u0441 export const throttle = (fn: Function, ms: number) => {   \/\/ \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438   let ready = true;   const throttled = (...args: any[]) => {     \/\/ \u0435\u0441\u043b\u0438 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `false`     if (!ready) return;     \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043b\u043b\u0431\u0435\u043a     fn(...args);     \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440     ready = false;     const timer = setTimeout(() => {       \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438       ready = true;       \/\/ \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440       clearTimeout(timer);     }, ms);   };   return throttled; };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 const throttledOnClick = throttle(onClick, 1000);  const btn = document.getElementById(\"btn\");  (btn as HTMLButtonElement).onclick = throttledOnClick;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u044b \u0440\u0430\u0437 \u043c\u044b \u043d\u0435 \u043d\u0430\u0436\u0438\u043c\u0430\u043b\u0438 \u043a\u043d\u043e\u043f\u043a\u0443, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 1 \u043d\u0435 \u0447\u0430\u0449\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0430 \u0432 \u0441\u0435\u043a. \u0422\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u0430\u043a <code>keydown<\/code> \u0438\u043b\u0438 <code>mousedown<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"rabota-s-asinhronnymi-funkciyami\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438<\/h2>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0442\u0438\u043f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 type ArgumentsType&lt;T> = T extends (...args: infer U) => any ? U : never; \/\/ \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043c\u0438\u0441\u0430 type UnwrapPromisify&lt;T> = T extends Promise&lt;infer U> ? U : T;  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 [ \u043e\u0448\u0438\u0431\u043a\u0430, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 ] \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `null` export const tryit = &lt;TFunction extends (...args: any) => any>(   fn: TFunction ) => {   return async (     ...args: ArgumentsType&lt;TFunction>   ): Promise&lt;[Error | null, UnwrapPromisify&lt;ReturnType&lt;TFunction>> | null]> => {     try {       return [null, await fn(...(args as any))];     } catch (err) {       return [err as any, null];     }   }; };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const getUsers = tryit(() =>   fetch(\"https:\/\/jsonplaceholder.typicode.com\/users?_limit=2\").then((r) =>     r.json()   ) ); const [error, users] = await getUsers(); console.log(error); \/\/ null console.log(users); \/\/ [ [user], [user] ]  \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0443\u0440\u043b\u0435 const getUsers2 = tryit(() =>   fetch(\"https:\/\/jsonplaceholder.typicod.com\/users?_limit=2\").then((r) =>     r.json()   ) ); const [error2, users2] = await getUsers2(); console.log(error2?.message); \/\/ Failed to fetch console.log(users2); \/\/ null<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const retry = async &lt;TResponse>(   \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f - \u043f\u0440\u043e\u043c\u0438\u0441   fn: (exit: (err: any) => void) => Promise&lt;TResponse>,   options: {     \/\/ \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a     times?: number;     \/\/ \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438     delay?: number | null;     \/\/ \u044d\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430     backoff?: (count: number) => number;   } ): Promise&lt;TResponse | void> => {   \/\/ \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f 3 \u043f\u043e\u043f\u044b\u0442\u043a\u0438   const times = options?.times ?? 3;   const delay = options?.delay;   const backoff = options?.backoff ?? null;    for (const i of list(1, times)) {     const [err, result] = (await tryit(fn)((err: any) => {       throw { _exited: err };     })) as [any, TResponse];     \/\/ \u0435\u0441\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0435\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442     if (!err) return result;     \/\/ \u0435\u0441\u043b\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0435\u0435     if (err._exited) throw err._exited;     \/\/ \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u043d\u043e, \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435     if (i === times) throw err;     \/\/ \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438     if (delay) await sleep(delay);     \/\/ \u044d\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430     if (backoff) await sleep(backoff(i));   } };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0443\u0440\u043b\u0435 const getUsers = () =>   fetch(\"https:\/\/jsonplaceholder.typicod.com\/users?_limit=2\").then((r) =>     r.json()   );  await retry(getUsers, { delay: 1000 }); \/\/ \u043f\u043e\u0441\u043b\u0435 3 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432 1 \u0441\u0435\u043a \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 `Uncaught TypeError: Failed to fetch`<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0437\u0430 \u043e\u0434\u0438\u043d \u0440\u0430\u0437 (\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Promise\/all\">Promise.all()<\/a>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 type WorkItemResult&lt;K> = {   index: number;   result: K;   error: any; }; \/\/ \u043a\u043b\u0430\u0441\u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 class AggregateError extends Error {   errors: Error[];   constructor(errors: Error[]) {     super();     this.errors = errors;   } }  \/\/ \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 const sort = &lt;T>(   arr: T[],   getter: (item: T) => number,   desc = false ) => {   if (!arr) return [];   const asc = (a: T, b: T) => getter(a) - getter(b);   const dsc = (a: T, b: T) => getter(b) - getter(a);   return arr.slice().sort(desc === true ? dsc : asc); }; \/\/ \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043f\u043e\u043f\u043e\u043b\u0430\u043c \/\/ \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 `condition` const fork = &lt;T>(   arr: T[],   condition: (item: T) => boolean ): [T[], T[]] => {   if (!arr) return [[], []];   return arr.reduce(     (acc, item) => {       const [a, b] = acc;       if (condition(item)) {         return [[...a, item], b];       } else {         return [a, [...b, item]];       }     },     [[], []] as [T[], T[]]   ); };  \/\/ \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f const parallel = async &lt;T, K>(   \/\/ \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439   limit: number,   \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438   arr: T[],   \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f   fn: (item: T) => Promise&lt;K> ): Promise&lt;K[]> => {   \/\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432   const work = arr.map((item, index) => ({     index,     item,   }));   \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432   const processor = async (res: (value: WorkItemResult&lt;K>[]) => void) => {     \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432     const results: WorkItemResult&lt;K>[] = [];      while (true) {       \/\/ \u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 - \u043c\u0435\u0442\u043e\u0434 `pop` \u043c\u0443\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432       const next = work.pop();        \/\/ \u0435\u0441\u043b\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u043d\u0447\u0438\u043b\u0438\u0441\u044c, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442       if (!next) return res(results);        \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b       const [error, result] = await tryit(fn)(next.item);        \/\/ \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u043c\u0430\u0441\u0441\u0438\u0432       results.push({         error,         result: result as K,         index: next.index,       });     }   };    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c   const queues = list(1, limit).map(() => new Promise(processor));    \/\/ \u0436\u0434\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439   const itemResults = (await Promise.all(queues)) as WorkItemResult&lt;K>[][];    \/\/ \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c   \/\/ \u0438 \u0434\u0435\u043b\u0438\u043c \u0435\u0433\u043e \u043f\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u044e \u043e\u0448\u0438\u0431\u043e\u043a   const [errors, results] = fork(     sort(itemResults.flat(), (r) => r.index),     (x) => !!x.error   );    \/\/ \u0435\u0441\u043b\u0438 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0438   if (errors.length > 0) {     \/\/ \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435     throw new AggregateError(errors.map((error) => error.error));   }    \/\/ \u0438\u043d\u0430\u0447\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432   return results.map((r) => r.result); };<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0443\u0442\u0435\u0439 const urls = [   \"https:\/\/jsonplaceholder.typicode.com\/users\/1\",   \"https:\/\/jsonplaceholder.typicode.com\/posts\/1\",   \"https:\/\/jsonplaceholder.typicode.com\/todos\/1\", ]; \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u0443\u0440\u043b\u0443 const fetcher = (url: string) => fetch(url).then((r) => r.json()); \/\/ \u0434\u0430\u043d\u043d\u044b\u0435 const data = await parallel(3, urls, async (url) => await fetcher(url)); console.log(data); \/\/ [ [user], [post], [todo] ]  const urls2 = [   \"https:\/\/jsonplaceholder.typicode.com\/users\/1\",   \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0443\u0440\u043b\u0435   \"https:\/\/jsonplaceholder.typicod.com\/posts\/1\",   \"https:\/\/jsonplaceholder.typicode.com\/todos\/1\", ]; const [err, data2] = await tryit(parallel)(   3,   urls2,   \/\/ \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0442\u0438\u043f\u0430   async (url) => await fetcher(url as string) ); console.log(data2); \/\/ null \/\/ \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0442\u0438\u043f\u0430 console.log((err as AggregateError).errors); \/\/ [TypeError: Failed to fetch...] console.log((err as AggregateError).errors[0].message); \/\/ Failed to fetch<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0435\u043c \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435. \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0443 \u0443\u0442\u0438\u043b\u0438\u0442, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>Radash<\/code>, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043c\u043d\u0435 \u043d\u0435 \u0442\u0430\u043a\u0438\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435 \u0438 \u043d\u0435 \u0437\u0440\u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438 happy coding!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<p><a href=\"https:\/\/cloud.timeweb.com\/vds-promo-8-rub?utm_source=habr&amp;utm_medium=blog_1560_476&amp;utm_campaign=habr&amp;utm_content=1560_476\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/p-\/u9\/l2\/p-u9l27ynelxi92bcmdxhu76ma8.png\" data-src=\"https:\/\/habrastorage.org\/webt\/p-\/u9\/l2\/p-u9l27ynelxi92bcmdxhu76ma8.png\"\/><\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/686824\/\"> https:\/\/habr.com\/ru\/company\/timeweb\/blog\/686824\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/um\/fe\/t_\/umfet_kngorlggfmgokzowwtsuu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/um\/fe\/t_\/umfet_kngorlggfmgokzowwtsuu.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/radash-docs.vercel.app\/docs\/getting-started\">Radash<\/a> \u2014 \u044d\u0442\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 <a href=\"https:\/\/lodash.com\/\">Lodash<\/a>, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u043d\u0430\u0431\u043e\u0440 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 (\u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439), \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 <a href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a>. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/rayepps\/radash\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0441\u0435\u0431\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0422\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f\u044b.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0432\u043e\u0442 <a href=\"https:\/\/my-js.org\/docs\/other\/snippets-js\">\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0441\u043d\u0438\u043f\u043f\u0435\u0442\u043e\u0432 JavaScript<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0447\u0435\u0433\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043f\u0440\u043e\u0449\u0435.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-338044","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338044","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=338044"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338044\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=338044"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=338044"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=338044"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}