index.js 11 KB

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