Browse Source

Javascript Async: Promise Homework done

Vladimir 2 years ago
parent
commit
373e0e7fb7
2 changed files with 162 additions and 0 deletions
  1. 23 0
      HW 12/index.html
  2. 139 0
      HW 12/main.js

+ 23 - 0
HW 12/index.html

@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+</head>
+<body>
+    <ul class="select__container">
+        <li class="select__item">
+            <label for="country" class="select__label">Страна</label>
+            <select name="country" id="country" class="select__select"></select>
+        </li>
+        <li class="select__item">
+            <label for="city" class="select__label">Город</label>
+            <select name="city" id="city" class="select__select"></select>
+        </li>
+    </ul>
+    <div class="contanier"></div>
+    <script src="main.js"></script>
+</body>
+</html>

+ 139 - 0
HW 12/main.js

@@ -0,0 +1,139 @@
+//Асинхронщина в JS, callback hell
+//Задание
+let request = new XMLHttpRequest();
+let selectCountry = document.querySelector("#country");
+let selectCity    = document.querySelector("#city");
+
+request.open("GET", "https://raw.githubusercontent.com/David-Haim/CountriesToCitiesJSON/master/countriesToCities.json", true);
+
+request.addEventListener("readystatechange", function() {
+    if(request.readyState == 4) {
+        let countriesToCitiesJSON = JSON.parse(request.response);
+
+        drawCountriesInSelect(countriesToCitiesJSON);
+        drawCityInSelect(countriesToCitiesJSON);
+
+        selectCountry.addEventListener("input", function() {
+            drawCityInSelect(countriesToCitiesJSON);
+        });
+    }
+});
+
+request.send();
+
+let drawCountriesInSelect = function(obj) {
+    for(let [key, value] of Object.entries(obj)) {
+        let option = document.createElement("option");
+
+        option.text = key;
+
+        selectCountry.appendChild(option);
+    }
+}
+
+let drawCityInSelect = function(obj) {
+    let countryIndex = selectCountry.selectedIndex;
+    let str = "";
+
+    for(let city of Object.entries(obj)[countryIndex][1]) {
+        str += `<option>${city}</option>`;
+    }
+
+    selectCity.innerHTML = str;
+}
+
+
+//Javascript Async: Promise Homework
+//fetch basic
+//fetch improved
+let container = document.querySelector(".contanier");
+
+function Table(container, url) { // Конструктор для сбора таблицы
+    this.url = url;         
+
+    let getObjForFetchRequest = function(url) {     // Получаю obj в зависимости от url, по факту эта функция запускает всю цепочку событий по отрисовки таблицы
+        fetch(url).then(res => res.json()).then(obj => createTable(obj));
+    };
+
+    let valueCreators = { // Тут я буду проверять кем является value, в цыкле for у функции createTable, строка или массив
+        String(value) {
+            if(value.includes("https://swapi.dev/api/")) { // Проверка на наличие строки "https://swapi.dev/api/" в value, если true то ложу в кнопку
+                return `<button>${value}</button>`;
+            } else {
+                return value;
+            }
+        },
+        Array(value) {
+            let str = "";
+
+            for(let item of value) {
+                if(item.includes("https://swapi.dev/api/")) {
+                    str += `<button>${item}</button><br>`;
+                } else {
+                    str += item;
+                }
+            }
+
+            return str;
+        }
+    };
+
+    let createTable = function(obj) { // Собсна функция которая собирает таблицу
+        let str = "";
+
+        str += "<table>";
+
+        for(let [key, value] of Object.entries(obj)) {
+            let valueCreatorFunction = valueCreators[value.constructor.name];
+
+            str += `<tr><td>${key}</td><td>${valueCreatorFunction(value)}</td></tr>`; // Запуск valueCreatorFunction что бы корректно отрисовать строку или массив
+        };
+
+        str += "</table>";
+
+        container.innerHTML = str;
+    };
+
+    getObjForFetchRequest(url); // Одноразовый вызов функции для запуска цепочки по отрисовки таблицы 
+
+    let changeObjForFetchRequest = function(evt) { // Функция для слушателя событий "click" который будет запускать getObjForFetchRequest с url который находиться внутри кнопки
+        if(evt.target.tagName == "BUTTON") {
+            getObjForFetchRequest(evt.target.textContent);
+        }
+    }
+
+    container.addEventListener("click", changeObjForFetchRequest); 
+};
+
+let table = new Table(container, "https://swapi.dev/api/people/1/");
+
+
+//myfetch
+function myfetch(url){
+    return new Promise(function (resolve, reject){
+        let xhr = new XMLHttpRequest();
+
+        xhr.open("GET", url, true);
+
+        xhr.addEventListener("readystatechange", function() {
+            if(xhr.readyState == 4) {               // Если все хорошо то нужно передать в resolve объект
+                resolve(JSON.parse(xhr.response));
+            } else if (xhr.status > 500) {          // Если все не очень хорошо то вывести информацию об ошибке
+                reject(`Ошибка: ${xhr.status} ${xhr.statusText}`);
+            }
+        });
+
+        xhr.send();
+    })
+}
+
+myfetch('https://swapi.dev/api/people/1/')
+  .then(luke => console.log(luke));
+
+
+//race
+let delay = new Promise((resolve, reject) => {
+    setTimeout(() => resolve("delay"), 500); // Подобрать параметр delay так, что бы результат был неизвестен изначально не возможно, иногда myfetch выполняется 1-2 сек, а иногда 9 сек
+});
+  
+Promise.race([myfetch('https://swapi.dev/api/people/1/'), delay]).then(value => console.log(value));