let url = 'https://raw.githubusercontent.com/David-Haim/CountriesToCitiesJSON/master/countriesToCities.json'; let request = new XMLHttpRequest(); request.open("GET", url, true); request.onreadystatechange = () => { if (request.readyState == 4){ let countriesFromJson = JSON.parse(request.response); showCountry(countriesFromJson); countrySelect.oninput = () => { showCities(countrySelect.value, countriesFromJson); } } } request.send() function showCountry(obj){ for (let [key,val] of Object.entries(obj)){ let option = document.createElement('option'); option.innerText = key countrySelect.append(option) } showCities(countrySelect.value, obj); } function showCities(country, object){ citySelect.innerText = '' let citiesFromCurrentCountry = object[country]; citiesFromCurrentCountry.forEach((item) => { let option = document.createElement('option'); option.innerText = item citySelect.append(option) }); } ////////////////////////////////////////////////////////fetch basic, fetch improved let url2 = 'https://swapi.dev/api/people/1/'; let valueCreators = { String(value){ if(value.includes("https://swapi.dev/api/")){ return `` } else { return value } }, Array(value){ let str = ''; value.forEach((item) => { item.includes("https://swapi.dev/api/") ? str += `` : str += item }) return str } } function createTable(parent, obj){ let str = ''; for(let [key,value] of Object.entries(obj)){ let valueCreator = valueCreators[value.constructor.name]; if (typeof valueCreator === 'function'){ ///проверяем значение (есть ли для него нужный конструктор) str += `` } else { str += `` } } str += '
${key}${valueCreator(value)}
${key}${value}
' parent.innerHTML += str; } let startFetch = function (url,parent){ ////создает новую таблицу в том элементе где была кнопка fetch(url) .then(res => res.json()) .then(luke => createTable(parent, luke)) } startFetch(url2, container); container.addEventListener("click", (event) => { if(event.target.tagName == 'BUTTON'){ startFetch(event.target.textContent, event.target.parentElement) } }) // let startFetch = function (url){ ///// или можно все перезатирать и создавать новую (без наглядной вложенности) // fetch(url) ///// только в 72 строке изменить на parent.innerHTML = str; // .then(res => res.json()) // .then(luke => createTable(container, luke)) // } // startFetch(url2); // container.addEventListener("click", (event) => { // if(event.target.tagName == 'BUTTON'){ // startFetch(event.target.textContent) // } // }) /////////////////////////////////////////////// my fetch let url3 = 'https://swapi.dev/api/people/1/'; function myFetch (url){ return new Promise(function (resolve, reject){ const xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.onreadystatechange = () => { if(xhr.readyState == 4){ ///проверяем закончился ли запрос if (xhr.status == 200){ resolve(JSON.parse(xhr.response)) } else if (xhr.onerror || xhr.status != 200){ reject(new Error(`i have error for you ${xhr.status} ${xhr.statusText}`)) } } } xhr.send() }) } myFetch(url3).then(luke => console.log(luke)); ////////////////////race const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms)); Promise.race([myFetch(url3), delay(350)]).then(value => console.log(value));