|
@@ -0,0 +1,211 @@
|
|
|
|
+// 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', '<caption><b>Hero portfolio</b></caption>');
|
|
|
|
+ const heroTableHead = document.createElement('tr');
|
|
|
|
+ const heroTableBody= document.createElement('tr');
|
|
|
|
+ heroTableHead.innerHTML = Object.keys(JSONdata).map(key => `<th>${key}</th>`).join('');
|
|
|
|
+ heroTableBody.innerHTML = Object.values(JSONdata).map(item => `<td>${item}</td>`).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><b>${caption[0].toUpperCase() + caption.slice(1)}</b></caption>`);
|
|
|
|
+ const heroTableHead = document.createElement('tr');
|
|
|
|
+ const heroTableBody= document.createElement('tr');
|
|
|
|
+ heroTableHead.innerHTML = Object.keys(JSONdata).map(key => `<th>${key}</th>`).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);
|
|
|
|
+ })
|
|
|
|
+}
|