//Асинхронщина в 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 += ``; } 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 ``; } else { return value; } }, Array(value) { let str = ""; for(let item of value) { if(item.includes("https://swapi.dev/api/")) { str += `
`; } else { str += item; } } return str; } }; let createTable = function(obj) { // Собсна функция которая собирает таблицу let str = ""; str += ""; for(let [key, value] of Object.entries(obj)) { let valueCreatorFunction = valueCreators[value.constructor.name]; str += ``; // Запуск valueCreatorFunction что бы корректно отрисовать строку или массив }; str += "
${key}${valueCreatorFunction(value)}
"; 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));