|
@@ -0,0 +1,267 @@
|
|
|
+/*Светофор
|
|
|
+Используя асинхронную функцию и бесконечный цикл, просимулируйте светофор:
|
|
|
+
|
|
|
+Для отображения включения того или иного света используйте один или три DOM-элемента.
|
|
|
+Stage 2
|
|
|
+Сделайте trafficLight более универсальной - добавьте в параметры DOM-элемент для отображения, а так же время работы каждого цвета
|
|
|
+*/
|
|
|
+
|
|
|
+const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
|
|
|
+
|
|
|
+
|
|
|
+async function trafficLight(element, ms){
|
|
|
+ while (true){
|
|
|
+ //включаем зеленый
|
|
|
+ element.className = "svetoforGreen"
|
|
|
+ await delay(ms)
|
|
|
+ //включаем желтый
|
|
|
+ element.className = "svetoforYellow"
|
|
|
+ await delay(ms)
|
|
|
+ //включаем красный
|
|
|
+ element.className = "svetoforRed"
|
|
|
+ await delay(ms)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+trafficLight(svetofor, 3000)
|
|
|
+
|
|
|
+/*PedestrianTrafficLight
|
|
|
+Напишите упрощенный светофор для пешеходов
|
|
|
+Stage 2
|
|
|
+Используя Promise.race, domEventPromise и кнопку в DOM сделайте пешеходный светофор с кнопкой, который так же переключается по времени периодически.
|
|
|
+Stage 3
|
|
|
+Не давайте возможности пешеходам сильно наглеть - предусмотрите задержку, после которой будет работать кнопка.*/
|
|
|
+{
|
|
|
+ function domEventPromise(element, eventName) {
|
|
|
+ function executor(resolve) {
|
|
|
+ //happy hacking
|
|
|
+ function myEvent(event) {
|
|
|
+ console.log('click')
|
|
|
+ element.removeEventListener(eventName, myEvent)
|
|
|
+ resolve(event)
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ element.addEventListener(eventName, myEvent)
|
|
|
+
|
|
|
+ }
|
|
|
+ return new Promise(executor)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ async function PedestrianTrafficLight(element, ms) {
|
|
|
+ while (true) {
|
|
|
+ //включаем зеленый
|
|
|
+ element.className = "svetoforGreen"
|
|
|
+ await delay(ms)
|
|
|
+
|
|
|
+ //включаем красный
|
|
|
+
|
|
|
+ element.className = "svetoforRed"
|
|
|
+ await delay(2000)
|
|
|
+ await Promise.race([
|
|
|
+ delay(ms - 2000),
|
|
|
+ domEventPromise(padestrianSvetoforButton, 'click')
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ PedestrianTrafficLight(padestrianSvetofor, 8000)
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/* speedtest
|
|
|
+Написать асинхронную функцию
|
|
|
+
|
|
|
+async function speedtest(getPromise, count,parallel=1){
|
|
|
+....
|
|
|
+ return {
|
|
|
+ duration,
|
|
|
+ querySpeed, //средняя скорость одного запроса
|
|
|
+ queryDuration, //
|
|
|
+ parallelSpeed,
|
|
|
+ parallelDuration
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+speedtest(() => delay(1000), 10, 10 ).then(result => console.log(result))
|
|
|
+// {duration: 10000,
|
|
|
+// querySpeed: 0.001, //1 тысячная запроса за миллисекунду
|
|
|
+// queryDuration: 1000, //1000 миллисекунд на один реальный запрос в среднем
|
|
|
+// parallelSpeed: 0.01 // 100 запросов за 10000 миллисекунд
|
|
|
+// parallelDuration: 100 // 100 запросов за 10000 миллисекунд
|
|
|
+speedtest(() => fetch('http://swapi.dev/api/people/1').then(res => res.json()), 10, 5)
|
|
|
+
|
|
|
+где:
|
|
|
+count - количество повторов
|
|
|
+parallel - количество одновременных запросов/промисов в одном повторе
|
|
|
+getPromise - функция, которая умеет вернуть нужный Вам промис для тестирования скорости его работы
|
|
|
+которая будет в цикле count раз создавать parallel промисов с помощью переданной функции getPromise, дожидаться выполнения всех parallel промисов, после чего цикл повторяется.
|
|
|
+Замерить время общее время выполнения, и вычислить:
|
|
|
+duration, общую длительность работы цикла
|
|
|
+parallelDuration, среднее время обработки запроса параллельно (за какое время исполнилось parallel*count промисов),
|
|
|
+paralledSpeed, скорость в запросах в миллисекунду
|
|
|
+queryDuration, реальное среднее время запроса (отталкиваясь от count и времени работы цикла).
|
|
|
+querySpeed, реальное средняя скорость запроса
|
|
|
+Эти переменные вернуть в одном объекте-результате (см. заготовку выше)
|
|
|
+Для отладки попробуйте на delay (пример выше есть, реальное время будет отличаться на единицы-десятки миллисекунд). Потом можете попробовать на swapi.dev. Не создавайте чрезмерно много параллельных запросов.
|
|
|
+*/
|
|
|
+{
|
|
|
+ function makeProfileTimer() {
|
|
|
+ const t0 = performance.now()
|
|
|
+ return () => {
|
|
|
+ const t1 = performance.now()
|
|
|
+ return t1 - t0
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*var timer = makeProfileTimer()
|
|
|
+ alert('Замеряем время работы этого alert')
|
|
|
+ alert(timer())*/
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ async function speedtest(getPromise, count, parallel = 1) {
|
|
|
+
|
|
|
+ let durationStart = makeProfileTimer() //засекаем время старта всего цикла (duration)
|
|
|
+
|
|
|
+ for (let i = 0; i < count; i++) { // в этом цикле задаем количество повторов count
|
|
|
+ let parallelArr = [] //тут будут храниться промисы
|
|
|
+ for (let p = 0; p < parallel; p++) { //добавляем нужное количество промисов в массив для запуска теста с параллельно запущеніми промисами
|
|
|
+ parallelArr.push(getPromise())
|
|
|
+ }
|
|
|
+
|
|
|
+ await Promise.all(parallelArr) // тут запускаем все промисы из одной паралели и ждем пока зарезолвятся все
|
|
|
+ }
|
|
|
+
|
|
|
+ let duration = durationStart() //записываем в duration разницу между точкой старта перед циклом и этой точкой
|
|
|
+ let parallelDuration = duration / (parallel * count)
|
|
|
+ let querySpeed = (parallel * count) / duration
|
|
|
+ let queryDuration = duration / count
|
|
|
+ let parallelSpeed = (parallel * count) / duration
|
|
|
+
|
|
|
+ ////
|
|
|
+ return {
|
|
|
+ duration,
|
|
|
+ querySpeed, //средняя скорость одного запроса
|
|
|
+ queryDuration, //
|
|
|
+ parallelSpeed,
|
|
|
+ parallelDuration
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ speedtest(() => fetch('http://swapi.dev/api/people/1').then(res => res.json()), 10, 5).then(x => console.log(x))
|
|
|
+}
|
|
|
+ /*gql
|
|
|
+Напишите функцию gql, которая осуществляет GraphQL запрос. Функция принимает три параметра:
|
|
|
+Эндпоинт - адрес сервера. Например "http://shop-roles.node.ed.asmer.org.ua/graphql"
|
|
|
+Текст запроса (query). Например:
|
|
|
+query cats($q: String){
|
|
|
+ CategoryFind(query: $q){
|
|
|
+ _id name
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Параметры(переменные) (variables) запроса объектом. Например:
|
|
|
+{
|
|
|
+ q: "[{}]"
|
|
|
+}
|
|
|
+Функция должна возвращать промис, созданный fetch со следующими настройками:
|
|
|
+Метод POST
|
|
|
+Заголовки:
|
|
|
+Content-Type - application/json
|
|
|
+Accept- application/json
|
|
|
+Тело - JSON, объект с двумя ключами - query (текст запроса) и variables
|
|
|
+Проверьте вашу функцию:*/
|
|
|
+{
|
|
|
+ ;(async () => {
|
|
|
+ const catQuery = `query cats($q: String){
|
|
|
+ CategoryFind(query: $q){
|
|
|
+ _id name
|
|
|
+ }
|
|
|
+ }`
|
|
|
+ const cats = await gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, {q: "[{}]"})
|
|
|
+ console.log(cats) //список категорий с _id name и всем таким прочим
|
|
|
+
|
|
|
+
|
|
|
+ const loginQuery = `query login($login:String, $password:String){
|
|
|
+ login(login:$login, password:$password)
|
|
|
+ }`
|
|
|
+
|
|
|
+ const token = await gql("http://shop-roles.node.ed.asmer.org.ua/graphql", loginQuery ,{login: "test457", password: "123123"})
|
|
|
+ console.log(token)
|
|
|
+ })()
|
|
|
+
|
|
|
+
|
|
|
+ async function gql(endpoint, myquery, variables) {
|
|
|
+ let result = await fetch(endpoint, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json;charset=utf-8',
|
|
|
+ 'Accept': 'application/json'
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ query: myquery,
|
|
|
+ variables: variables
|
|
|
+ })
|
|
|
+ }).then(res => res.json())
|
|
|
+
|
|
|
+ return result
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*jwtDecode
|
|
|
+Напишете функцию jwtDecode, которая принимает единственный параметр token и возвращает информацию из переданного JWT токена.
|
|
|
+Алгоритм раскодирования:
|
|
|
+Разбить токен на три части. Разделитель - . (точка)
|
|
|
+Выделить среднюю часть.
|
|
|
+Используя функцию atob раскодировать среднюю часть из кодировки Base64, получив JSON
|
|
|
+Раскодировать JSON
|
|
|
+Вернуть раскодированные данные из JSON
|
|
|
+Учтите, что в качестве токена может быть передана какая-то дичь. В таком случае раскодировка не получится, и функция:
|
|
|
+Не должна сыпать красными матюками (ошибками) в консоль
|
|
|
+Должна просто вернуть undefined*/
|
|
|
+
|
|
|
+{
|
|
|
+ const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2MzIyMDVhZWI3NGUxZjVmMmVjMWEzMjAiLCJsb2dpbiI6InRlc3Q0NTciLCJhY2wiOlsiNjMyMjA1YWViNzRlMWY1ZjJlYzFhMzIwIiwidXNlciJdfSwiaWF0IjoxNjY4MjcyMTYzfQ.rxV1ki9G6LjT2IPWcqkMeTi_1K9sb3Si8vLB6UDAGdw"
|
|
|
+console.log(jwtDecode(token))
|
|
|
+//{
|
|
|
+// "sub": {
|
|
|
+// "id": "632205aeb74e1f5f2ec1a320",
|
|
|
+// "login": "test457",
|
|
|
+// "acl": [
|
|
|
+// "632205aeb74e1f5f2ec1a320",
|
|
|
+// "user"
|
|
|
+// ]
|
|
|
+// },
|
|
|
+// "iat": 1668272163
|
|
|
+//}
|
|
|
+
|
|
|
+function jwtDecode(token) {
|
|
|
+ let result;
|
|
|
+ try {
|
|
|
+ let secondPartToken = token.split('.')[1];
|
|
|
+ result = JSON.parse(atob(secondPartToken));
|
|
|
+ } catch (e) {
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+try {
|
|
|
+ console.log(jwtDecode()) //undefined
|
|
|
+ console.log(jwtDecode("дичь")) //undefined
|
|
|
+ console.log(jwtDecode("ey.ey.ey")) //undefined
|
|
|
+
|
|
|
+ console.log('до сюда доработало, а значит jwtDecode не матерился в консоль красным цветом')
|
|
|
+}
|
|
|
+finally{
|
|
|
+ console.log('ДЗ, видимо, окончено')
|
|
|
+}
|
|
|
+}
|