script.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // Светофор
  2. // Используя асинхронную функцию и бесконечный цикл, просимулируйте светофор:
  3. // Для отображения включения того или иного света используйте один или три DOM-элемента.
  4. // Stage 2
  5. // Сделайте trafficLight более универсальной - добавьте в параметры DOM-элемент для отображения, а так же время
  6. // работы каждого цвета
  7. traffic_light: {
  8. const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms));
  9. let trafficLightEl = document.createElement('div');
  10. document.body.append(trafficLightEl);
  11. trafficLightEl.classList.add('traffic-light');
  12. let red = document.createElement('div');
  13. trafficLightEl.append(red);
  14. red.classList.add('cell');
  15. let yellow = document.createElement('div');
  16. trafficLightEl.append(yellow);
  17. yellow.classList.add('cell');
  18. let green = document.createElement('div');
  19. trafficLightEl.append(green);
  20. green.classList.add('cell');
  21. async function trafficLight(greenEl, yellowEl, redEl, greenTime, yellowTime, redTime) {
  22. while (true) {
  23. greenEl.classList.add('green');
  24. await delay(greenTime);
  25. greenEl.classList.remove('green');
  26. yellowEl.classList.add('yellow');
  27. await delay(yellowTime);
  28. yellowEl.classList.remove('yellow');
  29. redEl.classList.add('red');
  30. await delay(redTime);
  31. redEl.classList.remove('red');
  32. }
  33. }
  34. trafficLight(green, yellow, red, 6000, 1000, 6000);
  35. }
  36. // PedestrianTrafficLight
  37. // Напишите упрощенный светофор для пешеходов
  38. // Stage 2
  39. // Используя Promise.race, domEventPromise и кнопку в DOM сделайте пешеходный светофор с кнопкой, который так
  40. // же переключается по времени периодически.
  41. // Stage 3
  42. // Не давайте возможности пешеходам сильно наглеть - предусмотрите задержку, после которой будет работать
  43. // кнопка.
  44. pedestrian_traffic_light: {
  45. const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms));
  46. let pedestrianTrafficLightEl = document.createElement('div');
  47. document.body.append(pedestrianTrafficLightEl);
  48. pedestrianTrafficLightEl.classList.add('traffic-light');
  49. let red = document.createElement('div');
  50. pedestrianTrafficLightEl.append(red);
  51. red.classList.add('cell');
  52. let green = document.createElement('div');
  53. pedestrianTrafficLightEl.append(green);
  54. green.classList.add('cell');
  55. let button = document.createElement('button');
  56. button.innerText = 'switch';
  57. document.body.append(button);
  58. function domEventPromise(element, eventName) {
  59. function executor(resolve) {
  60. function myEvent(event) {
  61. element.disabled = true;
  62. element.removeEventListener(eventName, myEvent);
  63. setTimeout(() => resolve(event), 2000);
  64. }
  65. element.disabled = false;
  66. element.addEventListener(eventName, myEvent)
  67. }
  68. return new Promise(executor);
  69. }
  70. async function pedestrianTrafficLight(ms) {
  71. while (true) {
  72. red.classList.add('red');
  73. await Promise.race([
  74. delay(ms),
  75. domEventPromise(button, 'click')
  76. ]);
  77. red.classList.remove('red');
  78. green.classList.add('green');
  79. await delay(ms);
  80. green.classList.remove('green');
  81. }
  82. }
  83. pedestrianTrafficLight(6000);
  84. }
  85. // speedtest
  86. // Написать асинхронную функцию, где:
  87. // count - количество повторов
  88. // parallel - количество одновременных запросов/промисов в одном повторе
  89. // getPromise - функция, которая умеет вернуть нужный Вам промис для тестирования скорости его работы
  90. // которая будет в цикле count раз создавать parallel промисов с помощью переданной функции getPromise,
  91. // дожидаться выполнения всех parallel промисов, после чего цикл повторяется.
  92. // Замерить время общее время выполнения, и вычислить:
  93. // duration, общую длительность работы цикла
  94. // parallelDuration, среднее время обработки запроса параллельно (за какое время исполнилось parallel*count
  95. // промисов),
  96. // paralledSpeed, скорость в запросах в миллисекунду
  97. // queryDuration, реальное среднее время запроса (отталкиваясь от count и времени работы цикла).
  98. // querySpeed, реальное средняя скорость запроса
  99. // Эти переменные вернуть в одном объекте-результате (см. заготовку выше)
  100. // Для отладки попробуйте на delay (пример выше есть, реальное время будет отличаться на единицы-десятки
  101. // миллисекунд). Потом можете попробовать на swapi.dev. Не создавайте чрезмерно много параллельных запросов.
  102. speedtest: {
  103. const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms));
  104. function makeProfileTimer() {
  105. let t0 = performance.now();
  106. return function () {
  107. let t1 = performance.now();
  108. return t1 - t0;
  109. }
  110. }
  111. async function speedtest(getPromise, count, parallel = 1) {
  112. let timer = makeProfileTimer();
  113. for (let i = 0; i < count; i++) {
  114. let promises = [];
  115. for (let j = 0; j < parallel; j++) {
  116. promises.push(getPromise());
  117. }
  118. console.log(await Promise.all(promises));
  119. }
  120. let duration = timer();
  121. let parallelDuration = duration / (count * parallel);
  122. let parallelSpeed = 1 / parallelDuration;
  123. let queryDuration = duration / count;
  124. let querySpeed = 1 / queryDuration;
  125. return {
  126. duration,
  127. querySpeed, //средняя скорость одного запроса
  128. queryDuration, //
  129. parallelSpeed,
  130. parallelDuration
  131. }
  132. }
  133. speedtest(() => delay(1000), 10, 10).then(result => console.log(result));
  134. // {duration: 10000,
  135. // querySpeed: 0.001, //1 тысячная запроса за миллисекунду
  136. // queryDuration: 1000, //1000 миллисекунд на один реальный запрос в среднем
  137. // parallelSpeed: 0.01 // 100 запросов за 10000 миллисекунд
  138. // parallelDuration: 100 // 100 запросов за 10000 миллисекунд
  139. speedtest(() => fetch('http://swapi.dev/api/people/1').then(res => res.json()), 10, 5).then(result => console.log(result));
  140. }
  141. // gql
  142. // Напишите функцию gql, которая осуществляет GraphQL запрос. Функция принимает три параметра:
  143. // Эндпоинт - адрес сервера. Например "http://shop-roles.node.ed.asmer.org.ua/graphql"
  144. // Текст запроса (query).
  145. // Параметры(переменные) (variables) запроса объектом
  146. // Функция должна возвращать промис, созданный fetch со следующими настройками:
  147. // Метод POST
  148. // Заголовки:
  149. // Content-Type - application/json
  150. // Accept- application/json
  151. // Тело - JSON, объект с двумя ключами - query (текст запроса) и variables
  152. gql: {
  153. function gql(endpoint, query, variables) {
  154. return fetch(endpoint, {
  155. method: 'POST',
  156. headers: {
  157. 'Content-Type': 'application/json',
  158. 'Accept': 'application/json'
  159. },
  160. body: JSON.stringify({
  161. query,
  162. variables
  163. }),
  164. }).then(response => response.json());
  165. }
  166. (async () => {
  167. const catQuery = `query cats($q: String){
  168. CategoryFind(query: $q){
  169. _id name
  170. }
  171. }`
  172. const cats = await gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, { q: "[{}]" })
  173. console.log(cats) //список категорий с _id name и всем таким прочим
  174. const loginQuery = `query login($login:String, $password:String){
  175. login(login:$login, password:$password)
  176. }`
  177. const token = await gql("http://shop-roles.node.ed.asmer.org.ua/graphql", loginQuery, { login: "test457", password: "123123" })
  178. console.log(token)
  179. })()
  180. }
  181. // jwtDecode
  182. // Напишете функцию jwtDecode, которая принимает единственный параметр token и возвращает информацию из
  183. // переданного JWT токена.
  184. // Алгоритм раскодирования:
  185. // Разбить токен на три части. Разделитель - . (точка)
  186. // Выделить среднюю часть.
  187. // Используя функцию atob раскодировать среднюю часть из кодировки Base64, получив JSON
  188. // Раскодировать JSON
  189. // Вернуть раскодированные данные из JSON
  190. // Учтите, что в качестве токена может быть передана какая-то дичь. В таком случае раскодировка не получится,
  191. // и функция:
  192. // Не должна сыпать красными матюками (ошибками) в консоль
  193. // Должна просто вернуть undefined
  194. jwtDecode: {
  195. const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2MzIyMDVhZWI3NGUxZjVmMmVjMWEzMjAiLCJsb2dpbiI6InRlc3Q0NTciLCJhY2wiOlsiNjMyMjA1YWViNzRlMWY1ZjJlYzFhMzIwIiwidXNlciJdfSwiaWF0IjoxNjY4MjcyMTYzfQ.rxV1ki9G6LjT2IPWcqkMeTi_1K9sb3Si8vLB6UDAGdw";
  196. function jwtDecode(token) {
  197. let result;
  198. try {
  199. let mediumStr = token.split('.')[1];
  200. result = JSON.parse(atob(mediumStr));
  201. } catch (e) {
  202. }
  203. return result;
  204. }
  205. console.log(jwtDecode(token));
  206. //{
  207. // "sub": {
  208. // "id": "632205aeb74e1f5f2ec1a320",
  209. // "login": "test457",
  210. // "acl": [
  211. // "632205aeb74e1f5f2ec1a320",
  212. // "user"
  213. // ]
  214. // },
  215. // "iat": 1668272163
  216. //}
  217. try {
  218. console.log(jwtDecode()); //undefined
  219. console.log(jwtDecode("дичь")); //undefined
  220. console.log(jwtDecode("ey.ey.ey")); //undefined
  221. console.log('до сюда доработало, а значит jwtDecode не матерился в консоль красным цветом');
  222. }
  223. finally {
  224. console.log('ДЗ, видимо, окончено');
  225. }
  226. }