// Javascript Async: Promise Homework // fetch basic // -------------УСЛОВИЕ------------- // С помощью следующего кода считать и вывести информацию о Люке Скайвокере: // fetch('https://swapi.dev/api/people/1/') // .then(res => res.json()) // .then(luke => console.log(luke)) // Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра: // DOM - элемент, в котором строится таблица // JSON, который нужно отобразить. // -------------РЕШЕНИЕ------------- const task02block = document.createElement('div'); task02block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px"; const task02title = document.createElement('h2'); task02title.innerText = 'Task-02 Fetch basic'; root.appendChild(task02block); task02block.appendChild(task02title); function drawTable(block, JSONdata) { const heroTable = document.createElement('table'); heroTable.innerHTML = ""; heroTable.border = "1"; heroTable.style.maxWidth="1000px"; heroTable.insertAdjacentHTML('beforeend', 'Hero portfolio'); const heroTableHead = document.createElement('tr'); const heroTableBody= document.createElement('tr'); heroTableHead.innerHTML = Object.keys(JSONdata).map(key => `${key}`).join(''); heroTableBody.innerHTML = Object.values(JSONdata).map(item => `${item}`).join('').split(',').join(', '); heroTable.appendChild(heroTableHead); heroTable.appendChild(heroTableBody); block.appendChild(heroTable); } let url1 = 'https://swapi.dev/api/people/1/'; fetch(url1) .then(res => res.json()) .then(luke => drawTable(task02block, luke)) // fetch improved // -------------УСЛОВИЕ------------- // Расширить функцию отображения: // Если одно из полей строка или массив. // Если строки или строка содержат в себе https://swapi.dev/api/, то выводить вместо текста строки кнопку, при нажатии на которую: // делается fetch данных по этой ссылке // функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе. // -------------РЕШЕНИЕ------------- const task03block = document.createElement('div'); task03block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px"; const task03title = document.createElement('h2'); const task03fetchBlock = document.createElement('div'); task03title.innerText = 'Task-03 Fetch improved'; root.appendChild(task03block); task03block.appendChild(task03title); task03block.appendChild(task03fetchBlock); function drawTableImproved(block, JSONdata, url) { block.innerHTML = ''; const link = 'https://swapi.dev/api/'; const heroTable = document.createElement('table'); heroTable.innerHTML = ""; heroTable.border = "1"; heroTable.style.maxWidth="1000px"; let caption=url.split('/')[4]; heroTable.insertAdjacentHTML('beforeend', `${caption[0].toUpperCase() + caption.slice(1)}`); const heroTableHead = document.createElement('tr'); const heroTableBody= document.createElement('tr'); heroTableHead.innerHTML = Object.keys(JSONdata).map(key => `${key}`).join(''); for (let item of Object.values(JSONdata)) { const tableBodyCell = document.createElement('td'); if (isNaN(item)&&item.includes(link)) { const btnBodyCell = document.createElement('button'); btnBodyCell.style.margin = '5px'; btnBodyCell.value = item; btnBodyCell.innerText = "Go to"; url = item; btnBodyCell.onclick = () => {fetchFunc( btnBodyCell.value)}; tableBodyCell.appendChild(btnBodyCell); } else { if (Array.isArray(item) && item.filter(elem => elem.includes(link)).length) { let i = 1; for (let subItem of item) { const btnBodyCell = document.createElement('button'); btnBodyCell.style.margin = '5px'; btnBodyCell.value = subItem; btnBodyCell.innerText = 'Go to ' + i; url=subItem; btnBodyCell.onclick = () => {fetchFunc(btnBodyCell.value)}; tableBodyCell.appendChild(btnBodyCell); i++; } } else { tableBodyCell.innerText = item; } } heroTableBody.appendChild(tableBodyCell); } heroTable.appendChild(heroTableHead); heroTable.appendChild(heroTableBody); block.appendChild(heroTable); } let url = 'https://swapi.dev/api/people/1/'; function fetchFunc(url) { fetch(url) .then(res => res.json()) .then(luke => drawTableImproved(task03fetchBlock, luke, url)) } fetchFunc(url); // myfetch // -------------УСЛОВИЕ------------- // Используя XMLHTTPRequest, напишите промисифицированную функцию myfetch, т.е.функцию, которая возвращает промис, // и работает схоже с fetch, только в один этап: // myfetch('https://swapi.dev/api/people/1/') // .then(luke => console.log(luke)) // Функция myfetch ожидает что ответ будет в формате JSON(используйте JSON.parse(response.text)) // В случае ошибок(request.onerror или request.status не 200) не забудьте вызывать reject // function myfetch(url){ // return new Promise(function (resolve, reject){ // const xhr = new XMLHTTPRequest() // ///... // }) // } // -------------РЕШЕНИЕ------------- const task04block = document.createElement('div'); task04block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px"; const task04title = document.createElement('h2'); const task04fetchBlock = document.createElement('div'); task04title.innerText = 'Task-04 My fetch'; root.appendChild(task04block); task04block.appendChild(task04title); task04block.appendChild(task04fetchBlock); function myfetch(url) { return new Promise(function(resolve, reject) { const xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onload = function() { if (this.status == 200) { resolve(JSON.parse(xhr.responseText)); } else { var error = new Error(this.statusText); error.code = this.status; alert(error); reject(error); } }; xhr.onerror = function() {reject(new Error("Network Error")); }; xhr.send(); }); } myfetch(url) .then(luke => { console.log(luke); drawTableImproved(task04fetchBlock, luke, url) } ); // race // -------------УСЛОВИЕ------------- // Используя Promise.race запустите запрос на API(myfetch) параллельно с delay. // По результату определите, что было быстрее, запрос по сети, или определенный интервал времени. // Подберите параметр delay так, чтобы результат был неизвестен изначально, и при многократных запусках быстрее был то delay, // то myfetch. // -------------РЕШЕНИЕ------------- const task05block = document.createElement('div'); task05block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px"; const task05title = document.createElement('h2'); const task05fetchBlock = document.createElement('div'); task05title.innerText = 'Task-05 race'; const runPromisesBtn = document.createElement('button'); runPromisesBtn.innerText = 'Run promises'; runPromisesBtn.style = 'margin-bottom:20px'; root.appendChild(task05block); task05block.appendChild(task05title); task05block.appendChild(runPromisesBtn); task05block.appendChild(task05fetchBlock); runPromisesBtn.onclick = () => { task05fetchBlock.innerHTML = ''; const delay = async (ms) => await new Promise((resolve, reject) => setTimeout(() => resolve('2-nd promise'), ms)); Promise.race([myfetch(url), delay(100)]).then((value) => { console.log(value); const firstPromise = document.createElement('p'); firstPromise.innerText = `Faster was ${JSON.stringify(value)}`; task05fetchBlock.appendChild(firstPromise); }) }