diff --git a/lessons/lesson04/lesson.md b/lessons/lesson04/lesson.md index 4152392..a4b3332 100644 --- a/lessons/lesson04/lesson.md +++ b/lessons/lesson04/lesson.md @@ -657,4 +657,4 @@ describe('createCalculatorUI', () => { -Опрос о занятии \ No newline at end of file +Опрос о занятии diff --git a/lessons/lesson06/code/smart-getter/index.html b/lessons/lesson06/code/smart-getter/index.html index 8fe8d42..79147bf 100644 --- a/lessons/lesson06/code/smart-getter/index.html +++ b/lessons/lesson06/code/smart-getter/index.html @@ -1,59 +1,91 @@ - - - Safe Getter - - - - -
- - - -
-

Задача: Реализация аналога функции _.get из lodash

- -

Минимальный набор знаний

- - - - -

Что нужно сделать

-

- Реализуйте функцию get, которая позволяет безопасно получать значения из вложенных объектов по - строковому пути. Эта функция должна работать аналогично методу _.get из библиотеки lodash. -

-

+  
+    Safe Getter
+    
+  
+
+  
+    
+ + + +
+

Задача: Реализация аналога функции _.get из lodash

+ +

Минимальный набор знаний

+
    +
  • + Доступ к свойствам объекта (через точку и скобки): - + obj.property или obj["property"].
    + Квадратные скобки позволяют использовать переменную с именем свойства. + Подробнее: + MDN: Работа с объектами +
  • +
  • + Работа с вложенными объектами: - Для доступа к + свойствам внутри других объектов используйте последовательный доступ: + obj.user.profile.name или + obj['user']['profile'].name - + Подробнее: + learn.javascript.ru: Объекты +
  • +
  • + Работа со строками и массивами: - Используйте + split() + для разбивки строки пути на части: + 'user.profile.name'.split('.'). +
  • +
  • + Проверка существования свойства:- Если обратиться к + несуществующему свойству, вернётся undefined. Можно + проверить через сравнение с undefined или оператор + in: 'key' in obj. + Подробнее: + learn.javascript.ru: Объекты +
  • +
  • + Условные конструкции:- Используйте + if для проверки условий, например: если свойство не + найдено, вернуть значение по умолчанию. +
  • +
  • + Объявление функций с несколькими аргументами +
  • +
  • + Обработка пустого пути - как проверить что строка или + другое значение "пустое" +
  • +
+ +

Что нужно сделать

+

+ Реализуйте функцию get, которая позволяет безопасно + получать значения из вложенных объектов по строковому пути. Эта функция + должна работать аналогично методу + _.get из библиотеки lodash. +

+

       /**
       * get: Smart getter for object props
       *
@@ -64,65 +96,101 @@ 

Что нужно сделать

* @param {any} fallbackValue */
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Описание в JSDocПояснение простыми словами
get: Smart getter for object propsЭто функция, которая "умно" достает значения свойств из объекта.
Check tests for usage examplesПосмотри тесты, чтобы увидеть примеры использования этой функции.
@param {any} objПервый аргумент — объект, из которого нужно получить значение.
@param {string} propertyВторой аргумент — строка с путем к нужному свойству, например: 'user.profile.name'.
@param {any} fallbackValueТретий аргумент — значение по умолчанию, которое возвращается, если свойство не найдено.
- - -

Описание задачи

-
    -
  • Функция принимает объект, строку с путем до свойства (через точку или скобки, например, - 'user.profile.name' или 'user["profile"].name') и значение по умолчанию.
  • -
  • Возвращает значение, найденное по этому пути, либо значение по умолчанию, если путь не существует или где-то - на пути встречается undefined или null.
  • -
  • Если путь пустой, функция должна вернуть сам объект.
  • -
- -

Когда бывает полезна

-
    -
  • Когда структура объекта заранее неизвестна или может быть глубоко вложенной.
  • -
  • Когда нужно избежать ошибок при попытке доступа к несуществующим свойствам (например, - Cannot read property 'x' of undefined').
  • -
  • Для обработки данных из API, где некоторые поля могут отсутствовать.
  • -
- -

Где такая функция уже используется

-
    -
  • В библиотеке lodash функция называется _.get и широко применяется для безопасного доступа к - вложенным данным.
  • -
  • Аналогичные функции есть в других библиотеках, например, в Ramda (R.path), а также в различных - утилитах для JavaScript/TypeScript.
  • -
- -

Пример использования

-

+      
+        
+          
+            
+            
+          
+        
+        
+          
+            
+            
+          
+          
+            
+            
+          
+          
+            
+            
+          
+          
+            
+            
+          
+          
+            
+            
+          
+        
+      
Описание в JSDocПояснение простыми словами
get: Smart getter for object props + Это функция, которая "умно" достает значения свойств из объекта. +
Check tests for usage examples + Посмотри тесты, чтобы увидеть примеры использования этой функции. +
@param {any} obj + Первый аргумент — объект, из которого нужно получить значение. +
@param {string} property + Второй аргумент — строка с путем к нужному свойству, например: + 'user.profile.name'. +
@param {any} fallbackValue + Третий аргумент — значение по умолчанию, которое возвращается, + если свойство не найдено. +
+ +

Описание задачи

+
    +
  • + Функция принимает объект, строку с путем до свойства (через точку или + скобки, например, 'user.profile.name' или + 'user["profile"].name') и значение по умолчанию. +
  • +
  • + Возвращает значение, найденное по этому пути, либо значение по + умолчанию, если путь не существует или где-то на пути встречается + undefined или null. +
  • +
  • Если путь пустой, функция должна вернуть сам объект.
  • +
+ +

+ Когда + бывает полезна +

+
    +
  • + Когда структура объекта заранее неизвестна или может быть глубоко + вложенной. +
  • +
  • + Когда нужно избежать ошибок при попытке доступа к несуществующим + свойствам (например, + Cannot read property 'x' of undefined'). +
  • +
  • + Для обработки данных из API, где некоторые поля могут отсутствовать. +
  • +
+ +

Где такая функция уже используется

+
    +
  • + В библиотеке lodash функция называется _.get и широко + применяется для безопасного доступа к вложенным данным. +
  • +
  • + Аналогичные функции есть в других библиотеках, например, в Ramda + (R.path), а также в различных утилитах для + JavaScript/TypeScript. +
  • +
+ +

Пример использования

+

       const obj = { user: { profile: { name: 'Ivan' } } };
 
       get(obj, 'user.profile.name', 'No name'); // вернет 'Ivan'
@@ -131,10 +199,12 @@ 

Пример использования

get(obj, '', 'default'); // вернет весь объект obj
-

Ваша задача — реализовать эту функцию самостоятельно, не используя lodash или другие сторонние - библиотеки.

-
- - - - \ No newline at end of file +

+ Ваша задача — реализовать эту функцию самостоятельно, не используя + lodash или другие сторонние библиотеки. +

+
+ + diff --git a/lessons/lesson07/images/git_show.png b/lessons/lesson07/images/git_show.png new file mode 100644 index 0000000..5d6ab5d Binary files /dev/null and b/lessons/lesson07/images/git_show.png differ diff --git a/lessons/lesson07/lesson.md b/lessons/lesson07/lesson.md index b596c1f..07f677e 100644 --- a/lessons/lesson07/lesson.md +++ b/lessons/lesson07/lesson.md @@ -1 +1,531 @@ -# Lesson 7 +--- +title: Занятие 7 +description: "Использование СКВ: проблемы и решения, типовой порядок разработки с использованием Git. Использование CI/CD для проверки и доставки продукта" +--- + +# OTUS + +## Javascript Basic + + + +### Вопросы? + + + +## Использование СКВ + + + +Код это файлы (в нашем случае текст) + +Задачи: + +- версионирование кода +- просмотр изменений (что поменялось между версиями) +- применение изменений (как применить изменения, сделанные другим человеком) + + + +Частично задача решается современными редакторами + +- [WebStorm](https://www.jetbrains.com/help/webstorm/local-history.html) +- [VSCode](https://marketplace.visualstudio.com/items?itemName=xyz.local-history) + + + +[Система контроля версий](https://git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9E-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B5-%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D1%8F-%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B9) — это система, записывающая изменения в файл или набор файлов в течение времени и позволяющая вернуться позже к определённой версии. + + + +Почему [Git](https://git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9A%D1%80%D0%B0%D1%82%D0%BA%D0%B0%D1%8F-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%8F-Git)? + +- стандарт де-факто (вероятность встретить что-то другое очень мала) +- удобный инструмент (позволяет гибко делать очень разные вещи) +- позволяет работать без применения удаленного сервера + + + +## Вопросы? + + + +Для создания git репозитория нужно создать новую папку, и внутри нее выполнить команду `git init`. + +При этом там появится директория `.git`, которая служит для хранения служебных данных git. И вам станут доступны остальные команды. + + + +Немного о терминологии + + + +**Коммит** - [слепок файловой системы на определенный момент](https://git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git). + +Визуально же он представляет собой набор изменений + + + +```bash +git show 8d02d0fb279f7ae7bfc203642b00b48395412de5 +``` + + + + + +Атрибуты [коммита](https://github.com/vvscode/otus--javascript-basic/commit/8d02d0fb279f7ae7bfc203642b00b48395412de5): + +- sha-hash +- автор +- комментарий +- указатель на родительский коммит + + + +**Tag** / **Branch** - именованные указатели на коммит. + +**Tag** - указатель на конкретный коммит. + +**Branch** - последовательность коммитов. У этого списка есть `HEAD`, который указывает на последний коммит в ветке (в отличии от тега он не фиксированный) + + + +**Merge** - [слияние двух веток в одну](https://github.com/vvscode/otus--javascript-basic/pull/1/files) (когда изменения из второй ветки переносятся в первую) + + + +**Pull request** - [запрос переноса изменений](https://github.com/vvscode/otus--javascript-basic/pull/1/files) из одной ветки в другую (запрос на merge) + + + +**Remote** - удаленный репозиторий, с которым идет обмен изменениями. Может быть папкой на локальном диске, на сетевом диске или на удаленном сервере. Может быть один или несколько. + +Remote по умолчанию называют `origin`. + +```bash +# Посмотреть список remote +git remote +# Посмотреть подробнее +git remote -v +# Добавить новый remote +git remote add new-remote-name https://github.com/vvscode/otus--javascript-basic.git +``` + + + +[**Github**](https://github.com): + +- UI для git +- сервис централизованных репозиториев +- социальная сеть +- вспомогательные инструменты (CI, issues, projects, wiki, etc) + + + +## Вопросы? + + + +Как просмотреть историю коммитов? + +([И как сделать это красиво](https://stackoverflow.com/questions/1057564/pretty-git-branch-graphs)) + +```bash +git log + +git log -n 3 + +git log --all --graph --color --pretty=format:'%h^%C(white)%<(25,trunc)%an%C(reset)^%C(white)%<(31,trunc)%aD%C(reset)^%s%n^%C(dim white)%<(25,trunc)%ae%C(reset)^%>(31,trunc)%D%C(reset)%n' +``` + + + +Состояние git можно узнать при помощи + +```bash +git status +``` + + + +4 состояния файла + +- ignored (если файлы подходят под одну из масок в файле `.gitignore`) +- new / untracked +- staged +- committed + + + +В коммит попадают только изменения из фазы `staged` (из индекса). + +Для добавления файлов в индекс используется команда `git add` + +```bash +# Просмотреть состояние +git status + +# Добавить файл в индекс +git add file.js + +# Удалить файлы из индекса +# все +git reset +# конкретный файл +git reset file.js +``` + + + +Для просмотра изменений, которые попадут в коммит можно использовать команду `git diff` + + + +Для создания коммита используется команда `git commit`. + +Особенность - при выполнении команды без параметров откроется редактор (по умолчанию - [`vim`](https://www.linux.org.ru/forum/general/15057697)) + +Можно сразу задавать сообщение коммита с помощью + +```bash +git commit -m "My awesome message" +``` + + + +```bash +# Для создания веток используется команда +git checkout -b my-branch-name + +# Для переключения на коммит (ветку) +git checkout some-branch-name +git checkout some-tag-name +git checkout 8d02d0fb279f7ae7bfc203642b00b48395412de5 +``` + + + +## Вопросы? + + + +### Как работать с ветками? + +- [Удачная модель ветвления для Git](https://habr.com/ru/post/106912/) +- [Пожалуйста, перестаньте рекомендовать Git Flow](https://habr.com/ru/company/flant/blog/491320/) +- [GitHub Flow (ru)](https://habr.com/ru/post/346066/) +- [Gitlab Flow (ru)](https://habr.com/ru/company/intersystems/blog/354158/) + + + +На курсе модель такая ([Github flow](https://habr.com/ru/post/346066/)): + +- основная ветка `master` / `main` +- новое задание - от основной ветки создается ветка `a` (и от нее пуллреквест в основную) +- если до завершения задания вам нужно сделать другую задачу, которая не зависит от ветки `a` - от основной ветки вы создаете ветку `b` (и от нее пуллреквест в основную) +- если задача зависит от ветки `a` - вы создаете ветку `a1` от ветки `a` (и пуллреквест будет в ветку `a`) + + + +### Когда делать коммит? + +Когда вы достигли промежуточного (или конечного) результата или сделали осмысленный набор изменений. Делать коммиты "раз в день" или "когда закончу" - плохая практика. + + + +### Что писать в сообщение коммита? + +Что [и для чего] делает коммит. + +- [Как писать сообщения коммитов в Git](https://medium.com/grisme/%D0%BA%D0%B0%D0%BA-%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2-%D0%B2-git-9ed19ebc5ebf) +- [Как оформлять коммиты, чтобы потом не было больно](https://habr.com/ru/company/Voximplant/blog/276695/) +- [Как следует писать комментарии к коммитам](https://habr.com/ru/post/416887/) +- [Общепринятые коммиты](https://www.conventionalcommits.org/ru/v1.0.0-beta.4/) +- [lolcommits](https://lolcommits.github.io/) + + + +### Когда делать Pull Request? + +Без разницы. Удобно делать его сразу, тогда всегда можно посмотреть изменения из рабочей ветки. + +Если вы не хотите получать ревью - создайте `Draft` pull request (черновик). + + + +### Что писать в Pull Request? + +Что и зачем делается. Обычно это краткое описание задачи / проблемы. Иногда причины, почему выбран тот или иной подход. + +Для этого описания [можно создать шаблон](https://docs.github.com/en/free-pro-team@latest/github/building-a-strong-community/creating-a-pull-request-template-for-your-repository) (один раз) и пользоваться готовой структурой при каждом создании. + + + +## Вопросы? + + + +### Что использовать для работы с git? + + + +Варианты: + +- консоль + - [git](https://git-scm.com/downloads) + - [github cli](https://cli.github.com/) +- UI + - встроенный в редактор + - отдельная программа (например [Source Tree](https://www.sourcetreeapp.com/) или [Github Desktop](https://desktop.github.com/)) + + + +Основные команды: + +```bash +# Создать директорию +mkdir new-repo +# Перейти в репозиторий +cd new-repo +# Создать репозиторий +git init +# Создать файл +echo "Test" > 1.txt +# Посмотреть статус +git status +# Посмотреть diff +git diff +# Добавить файл в индекс +git add 1.txt +# Сделать коммит +git commit -m "Add 1.txt" +# Посмотреть лог +git log +# Создать новую ветку +git checkout -b new-branch +``` + + + +Основные команды для работы с удаленным сервером + +```bash +# Просмотреть список remote +git remote -v +# Добавить remote +git remote add remotename git@github.com:vvscode/otus--javascript-basic.git +# Скачать ветки с remote +git fetch +git fetch remotename +# Скачать изменения из remote для текущей ветки +git pull +# Отправить изменения в remote +git push +git push remotename branch-name +``` + + + +## Вопросы? + + + +## Github + + + +Профиль: + +- отображает основную информацию +- отображает список репозиториев +- отображает статистику +- можно сделать красивым ([1](https://www.youtube.com/watch?v=ECuqb5Tv9qI) и [2](https://github.com/abhisheknaiidu/awesome-github-profile-readme)) + + + +Репозитории: + +- личные и организаций +- публичные и приватные + + + +На странице репозитория отображается: + +- статистика (stars, forks, followers, contributors) +- содержимое README файла +- дополнительные ссылки (проект, issues, wiki) + + + +[Создание репозитория](https://github.com/new). + +При добавлении remote обратите внимание на тип url (ssh/https). + + + +Пример работы с репозиторием: + +- создать репозиторий +- создать новую ветку +- внести изменения в ветку +- создать pull request +- вмержить пуллреквест +- создать новую ветку из основной на основе прошлых изменений +- сделать новый pull request + + + +## Вопросы? + + + +Практика: + +- создать репозиторий (пустой) +- создать новую ветку +- в новой ветке создать файл README.md, добавить в него строчку '111' и сделать commit и push +- открыть пуллреквест с изменениями +- сбросить ссылку на pull request в чат + + + +Практика: + +- внести изменения в файл (поменять `111` на `222`) +- сделать коммит и отправить изменения в удаленную ветку (обновить pull request) +- сбросить ссылку в чат +- вмержить pull request +- локально переключиться на ветку по умолчанию +- подтянуть изменения с github +- создать новую ветку +- на основе изменений поменять `222` на `333` +- сделать коммит, push и открыть новый pull request +- сбросить ссылку в чат + + + +## Вопросы? + + + +## Автоматизация при работе с git + + + +Git поддерживает [хуки](https://git-scm.com/book/ru/v2/%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-Git-%D0%A5%D1%83%D0%BA%D0%B8-%D0%B2-Git). + +Хуки бывают: + +- клиентские +- серверные + +Их можно использовать для: + +- изменения кода +- формирования сообщений +- уведомления других программ о событиях + + + +Что полезного можно сделать с хуками? + + + +Серверные хуки доступны есть вы запускаете свой собственный [git сервер](https://git-scm.com/book/ru/v2/Git-%D0%BD%D0%B0-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B5-%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%B0%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80). Но мы работаем с Github и он это делать не позволяет. Зато Github поддерживает [веб-хуки](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/about-webhooks). + + + +Это использовалось для интеграции с сторонними системами (например [CI](https://habr.com/ru/post/352282/)). + +Тут есть варианты: + +- Jenkins +- TeamCity +- TravisCI +- CircleCI +- GitlabCI +- GithubActions + + + +Предпочтительнее использовать системы, которые поддерживают конфигурацию на уровне кода (TravisCI, CircleCI, GitlabCI, GithubActions) + + + +Для работы с интеграциями на курсе мы будем использовать [GithubActions](https://docs.github.com/en/free-pro-team@latest/actions) ([краткое введение](https://habr.com/ru/company/microsoft/blog/481502/)). + +Для подключения action нужно просто добавить [yml](https://ru.wikipedia.org/wiki/YAML) файл с нужной структурой. + +Примеры файлов можно посмотреть [здесь](https://github.com/otus-js-student/js--game-of-life/tree/master/.github/workflows) и [здесь](https://github.com/vvscode/otus--javascript-basic/tree/master/.github/workflows). + + + +## Вопросы? + + + +Практика: + +- в созданном репозитории создать новую ветку +- добавить туда [workflow для добавления комментария со ссылкой на codesandbox](https://github.com/otus-js-student/js--game-of-life/blob/master/.github/workflows/codesandbox-link-comment.yml) +- добавить в репозиторий файл [index.html](https://gist.github.com/vvscode/24df74ff0771e09bef53e40cba819c7a) с заголовком OTUS и выводом `alert` +- сделать commit, push, pull request +- убедиться что добавлен комментарий +- сбросить ссылку на pull request в чат + + + +## Вопросы? + + + +Короткая вводная по запуску тестов локально: + +```bash +# Перейти в директорию проекта (репозитория) + +# Инициализировать проект +npm init -y + +# Добавить node_modules в .gitignore +echo "node_modules" >> .gitignore + +# Установить jest +npm install jest --save-dev + +# Создать конфигурацию jest +npx jest --init + +# Проверить работу тестов при помощи +npm run test +``` + + + +Для настроек Jest выберите следующую конфигурацию + +```bash +✔ Would you like to use Typescript for the configuration file? … no +✔ Choose the test environment that will be used for testing › jsdom (browser-like) +✔ Do you want Jest to add coverage reports? … no +✔ Which provider should be used to instrument code for coverage? › v8 +✔ Automatically clear mock calls and instances between every test? … yes +``` + + + +### [Домашнее задание](https://github.com/vvscode/otus--javascript-basic/blob/master/lessons/lesson06/homework.md) + + + +Дополнительные материалы: + +- [Git Book(ru)](https://git-scm.com/book/ru/v2) +- [Git изнутри](https://habr.com/ru/post/468205/) +- [19 советов по повседневной работе с Git](https://habr.com/ru/company/mailru/blog/267595/) +- [Курс "Введение в Git"](https://ru.hexlet.io/courses/intro_to_git) +- [Скринкаст по Git](https://learn.javascript.ru/screencast/git) +- [Первоначальная настройка Git](https://hyperhost.ua/info/ru/pervonachalnaya-nastroyka-git) +- [30 команд Git, необходимых для освоения интерфейса командной строки Git](https://habr.com/ru/company/ruvds/blog/599929/) diff --git a/lessons/lesson07/task.md b/lessons/lesson07/task.md new file mode 100644 index 0000000..46df8b4 --- /dev/null +++ b/lessons/lesson07/task.md @@ -0,0 +1,27 @@ +--- +Зачем: Мы уходим из песочниц и начинам работать в условиях умеренно приближенным к реальным. Тут вы настраиваете ваше окружение (гит, редактор, тесты и линтеры), на практике создаете репозиторий и пуллреквест, получаете опыт код ревью (когда ваши задачи начинают проверяться преподавателями). По схеме из этого задания мы будем работать остаток курса. +--- + +### "Закрепление базового синтаксиса языка" + +Вам нужно будет: + +- создать репозиторий на гитхабе +- инициировать проект в репозитории +- решить предложенные в подготовительном курсе задачи (разместив код и тесты в директории `src`) +- покрыть решение задач автоматическими тестами +- сделать коммит (а лучше несколько - по одному на задание) +- открыть пуллреквест +- прислать ссылку на пуллревест в чат с преподавателем" + +#### Критерии оценки: + +- создан репозиторий на гитхабе - **1** +- создан npm-проект - **1** +- решены задания - **4** +- сделан пуллреквест - **2** +- настроен хаски и линтеры **\*** + +

+ +#### Задание считается принятым при 7 баллах diff --git a/lessons/lesson20/task.md b/lessons/lesson20/task.md index f60ca4f..d9b3743 100644 --- a/lessons/lesson20/task.md +++ b/lessons/lesson20/task.md @@ -14,14 +14,14 @@ Вам необходимо реализовать собственную версию метода .bind для функций в JavaScript. Встроенный `.bind` использовать нельзя ```js - function greet(greeting, punctuation) { - return greeting + ', ' + this.name + punctuation; - } +function greet(greeting, punctuation) { + return greeting + ", " + this.name + punctuation; +} - const person = { name: 'Алиса' }; - const greetAlice = greet.myBind(person, 'Привет'); +const person = { name: "Алиса" }; +const greetAlice = greet.myBind(person, "Привет"); - console.log(greetAlice('!')); // Ожидаемый результат: "Привет, Алиса!" +console.log(greetAlice("!")); // Ожидаемый результат: "Привет, Алиса!" ``` ### Цепочка @@ -29,8 +29,8 @@ Создать конструктор с методами, так, чтобы следующий код работал и делал соответствующие вещи те запуск кода ниже должен делать то, что говорят методы ```js - const u = new User(); - u.askName().askAge().showAgeInConsole().showNameInAlert(); +const u = new User(); +u.askName().askAge().showAgeInConsole().showNameInAlert(); ``` ### ForceConstructor @@ -42,15 +42,15 @@ Написать каррирующую функцию `curry` ( преобразующую функцию - из функции многих аргументов, получить множество функций одного аргумента) ```js - function sum2(x, y) { - return x + y; - } - function sum4(a, b, c, d) { - return a + b + c + d; - } - - curry(sum2)(1)(2); // 3 - curry(sum4)(2)(3)(4)(5); // 14 +function sum2(x, y) { + return x + y; +} +function sum4(a, b, c, d) { + return a + b + c + d; +} + +curry(sum2)(1)(2); // 3 +curry(sum4)(2)(3)(4)(5); // 14 ``` ## Критерии diff --git a/lessons/lesson22/task.md b/lessons/lesson22/task.md index a21cfb2..d2de837 100644 --- a/lessons/lesson22/task.md +++ b/lessons/lesson22/task.md @@ -17,8 +17,8 @@ - Функция promisify принимает на вход функцию, которая ожидает колбэк последним аргументом. Колбэк должен иметь стандартный вид: callback(error, result). - promisify возвращает новую функцию. При вызове эта функция возвращает промис, который: - - Резолвится с результатом, если в колбэк передан null или undefined вместо ошибки. - - Реджектится, если в колбэк передана ошибка. + - Резолвится с результатом, если в колбэк передан null или undefined вместо ошибки. + - Реджектится, если в колбэк передана ошибка. - Ваша функция должна корректно передавать все аргументы исходной функции, кроме колбэка. ```js @@ -37,9 +37,9 @@ function sum(a, b, cb) { const promisifiedSum = promisify(sum); promisifiedSum(2, 3) - .then(result => console.log(result)) // 5 - .catch(err => console.log(err)); // "Ошибка" -``` + .then((result) => console.log(result)) // 5 + .catch((err) => console.log(err)); // "Ошибка" +``` ### Parallel @@ -48,20 +48,13 @@ promisifiedSum(2, 3) **Требования:** - Класс должен называться `Parallel` и быть конструктором (использоваться через `new`). - - У экземпляра должны быть публичные методы: - - `job(fn)` — добавляет задачу (функцию), которую нужно выполнить. Метод должен поддерживать чейнинг (возвращать сам объект). - - - `done(cb)` — запускает выполнение всех добавленных задач. Когда все задачи завершены, вызывает колбэк `cb`, передавая ему массив результатов. - + - `job(fn)` — добавляет задачу (функцию), которую нужно выполнить. Метод должен поддерживать чейнинг (возвращать сам объект). + - `done(cb)` — запускает выполнение всех добавленных задач. Когда все задачи завершены, вызывает колбэк `cb`, передавая ему массив результатов. - Если не было добавлено ни одной задачи, `done` должен вызываться асинхронно. - - Пока не вызван `done`, задачи не запускаются. - - Если при создании объекта передать число (например, `new Parallel(3)`), оно задаёт максимальное количество задач, которые могут выполняться одновременно. - - Все задачи — функции, которые принимают один аргумент: функцию-колбэк `done(result)`, которую нужно вызвать по завершении задачи. - - Результаты должны возвращаться в том же порядке, в котором были добавлены задачи. - Продумайте выполнение задач без простоев @@ -70,10 +63,10 @@ promisifiedSum(2, 3) const runner = new Parallel(2); runner - .job(done => setTimeout(() => done('A'), 1000)) - .job(done => setTimeout(() => done('B'), 500)) - .job(done => setTimeout(() => done('C'), 300)) - .done(results => { + .job((done) => setTimeout(() => done("A"), 1000)) + .job((done) => setTimeout(() => done("B"), 500)) + .job((done) => setTimeout(() => done("C"), 300)) + .done((results) => { console.log(results); // ['A', 'B', 'C'] }); ``` @@ -89,46 +82,44 @@ runner Если запрос завершается успешно, функция возвращает результат как обычный `fetch`. Если все попытки завершились неудачно, функция должна вернуть ошибку. ```js -fetchRetry('https://dummyjson.com/products', 3, 1000) - .then(response => response.json()) - .then(data => console.log(data)) - .catch(error => console.error('Ошибка после всех попыток:', error)); +fetchRetry("https://dummyjson.com/products", 3, 1000) + .then((response) => response.json()) + .then((data) => console.log(data)) + .catch((error) => console.error("Ошибка после всех попыток:", error)); ``` **Требования:** -- Если запрос завершился с ошибкой (например, сеть недоступна или получен некорректный HTTP-статус), функция должна подождать указанную задержку и попробовать снова, пока не исчерпает все попытки. -- После успешного ответа функция должна вернуть результат без дополнительных попыток. -- Если все попытки неудачны, функция должна вернуть ошибку. - +- Если запрос завершился с ошибкой (например, сеть недоступна или получен некорректный HTTP-статус), функция должна подождать указанную задержку и попробовать снова, пока не исчерпает все попытки. +- После успешного ответа функция должна вернуть результат без дополнительных попыток. +- Если все попытки неудачны, функция должна вернуть ошибку. ### debounce Напишите функцию `debounce`, которая принимает два аргумента: -- функцию, которую нужно вызывать (например, обработчик событий) -- время задержки в миллисекундах - + +- функцию, которую нужно вызывать (например, обработчик событий) +- время задержки в миллисекундах + Функция `debounce` должна возвращать новую функцию-обёртку. Эта обёртка при каждом вызове не будет сразу запускать исходную функцию, а будет откладывать её выполнение на заданное количество миллисекунд. Если обёртку вызвать ещё раз до истечения задержки, предыдущий таймер отменяется и запускается новый отсчёт. В итоге исходная функция будет вызвана только один раз — спустя указанное время после последнего вызова обёртки ```js function onInput(event) { - console.log('Запрос к серверу:', event.target.value); + console.log("Запрос к серверу:", event.target.value); } const debouncedOnInput = debounce(onInput, 500); -inputElement.addEventListener('input', debouncedOnInput); +inputElement.addEventListener("input", debouncedOnInput); ``` В этом примере функция `onInput` будет вызываться только через 500 мс после того, как пользователь прекратил вводить текст, а не на каждое нажатие клавиши. **Что проверить:** -- Исходная функция вызывается не чаще одного раза за указанный интервал времени. - -- При частых вызовах обёртки исходная функция не запускается, пока не наступит "пауза". - -- Аргументы и контекст (`this`) корректно передаются в исходную функцию. +- Исходная функция вызывается не чаще одного раза за указанный интервал времени. +- При частых вызовах обёртки исходная функция не запускается, пока не наступит "пауза". +- Аргументы и контекст (`this`) корректно передаются в исходную функцию. ### serialProcess @@ -136,19 +127,15 @@ inputElement.addEventListener('input', debouncedOnInput); Функция-обработчик вызывается с четырьмя аргументами: -- `el` — текущий элемент массива, - -- `index` — индекс текущего элемента, - -- `list` — исходный массив, - -- `done` — функция, которую нужно вызвать по завершении обработки элемента, передав ей результат обработки. - +- `el` — текущий элемент массива, +- `index` — индекс текущего элемента, +- `list` — исходный массив, +- `done` — функция, которую нужно вызвать по завершении обработки элемента, передав ей результат обработки. Функция `serialProcess` должна возвращать промис, который резолвится после завершения обработки всех элементов, с массивом результатов в том же порядке, что и исходный массив. ```js -serialProcess([1,2,3,4,5], (el, index, list, done) => { +serialProcess([1, 2, 3, 4, 5], (el, index, list, done) => { console.log(`${el} start`); setTimeout(() => { console.log(`${el} end`); @@ -159,15 +146,10 @@ serialProcess([1,2,3,4,5], (el, index, list, done) => { **Требования:** -- Каждый элемент обрабатывается только после завершения предыдущего. - -- Обработчик может быть асинхронным (например, содержать `setTimeout`). - -- Результаты собираются в массив в том же порядке, что и исходные элементы. - -- После обработки всех элементов промис резолвится с массивом результатов. - - +- Каждый элемент обрабатывается только после завершения предыдущего. +- Обработчик может быть асинхронным (например, содержать `setTimeout`). +- Результаты собираются в массив в том же порядке, что и исходные элементы. +- После обработки всех элементов промис резолвится с массивом результатов. ## Критерии