|
@@ -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));
|