// fetch basic // Исследуйте сайт swapi.dev, рассмотрите JSON-ы, которые предоставляются этим сервисом // (например: https://swapi.dev/api/people/1/, https://swapi.dev/api/people/2/, https://swapi.dev/api/starships/12/ // С помощью следующего кода считать и вывести информацию о Люке Скайвокере: // Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра: // DOM - элемент, в котором строится таблица // JSON, который нужно отобразить. // fetch improved // Расширить функцию отображения: // Если одно из полей строка или массив. // Если строки или строка содержат в себе https://swapi.dev/api/ // То выводить вместо текста строки кнопку, при нажатии на которую: // делается fetch данных по этой ссылке // функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе. fetch_basic: { fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then(luke => { // console.log(luke); displayObjAsTable(document.body, luke); }) function displayObjAsTable(domElement, jsonElement, elemForRemoval) { let table = document.createElement('table'); table.border = 1; elemForRemoval?.remove(); domElement.append(table); Object.keys(jsonElement).forEach(key => { let tr = document.createElement('tr'); table.append(tr); let keyTd = document.createElement('td'); keyTd.innerText = key; tr.append(keyTd); let valueTd = document.createElement('td'); if (typeof jsonElement[key] == 'string' && jsonElement[key].includes('https://swapi.dev/api/')) { addButton(jsonElement[key], valueTd); } else if (Array.isArray(jsonElement[key])) { jsonElement[key].forEach((el) => { if (typeof el == 'string' && el.includes('https://swapi.dev/api/')) { addButton(el, valueTd); } }); } else { valueTd.innerText = jsonElement[key]; } tr.append(valueTd); }); } function addButton(value, valueTd) { let button = document.createElement('button'); button.innerText = 'Get ' + value.split('api/')[1]; button.addEventListener('click', () => { fetch(value) .then(res => res.json()) .then(data => { displayObjAsTable(valueTd, data, button); }) }); valueTd.append(button); } } // race // Используя Promise.race запустите запрос на API (swapi.dev) параллельно с delay. По результату определите, // что было быстрее, запрос по сети, или определенный интервал времени. Подберите параметр delay так, что бы // результат был неизвестен изначально, и при многократных запусках быстрее был то delay, то myfetch. race: { function delay(ms) { function executor(fulfill, reject) { setTimeout(() => fulfill(ms), ms); } return new Promise(executor); } let myfetch = fetch('https://swapi.dev/api/people/2/'); Promise.race([myfetch, delay(100)]).then((value) => { console.log(value); }); } // Promisify: confirm // Промисифицируйте confirm. Напишите функцию, которая возвращает промис, который переходит в состояние // fulfilled при нажатии "OK" и реджектится при нажатии "Cancel". Функция должна принимать строку для confirm: confirm: { function confirmPromise(text) { function executor(fulfill, reject) { if (confirm(text)) { fulfill(); } else { reject(); } } return new Promise(executor); } confirmPromise('Промисы это сложно?').then(() => console.log('не так уже и сложно'), () => console.log('respect за усидчивость и внимательность')) } // Promisify: prompt // Аналогично предыдующему заданию промисифицируйте prompt. В случае нажатия "ОК" промис резолвится и его // результатом становится текст, введенный пользователем в окне prompt. В случае нажатия "Отмены" - промис // реджектится. Параметром функции будет текст сообщения в prompt prompt: { function promptPromise(text) { function executor(fulfill, reject) { let answer = prompt(text); if (answer) { fulfill(answer); } else { reject(); } } return new Promise(executor); } promptPromise("Как тебя зовут?").then(name => console.log(`Тебя зовут ${name}`), () => console.log('Ну зачем морозиться, нормально же общались')) } // Promisify: LoginForm // Промисифицируйте конструктор LoginForm. В промисифицированную функцию передается DOM-элемент - родитель для // формы, В колбэке, предназначенном для получения логина и пароля в момент нажатия кнопки "Login...", который // вы назначаете в объекте LoginForm, зарезолвите промис. Результатом промиса должен быть объект с ключами // login и password, ключи должны содержать значения полей ввода. login_form: { function LoginForm(parent) { let form = document.createElement('form'); parent.append(form); let loginLabel = document.createElement('label'); loginLabel.innerText = 'Login: '; form.append(loginLabel); let login = new Login(form); let passwordLabel = document.createElement('label'); passwordLabel.innerText = 'Password: '; form.append(passwordLabel); let password = new Password(form, false); let submit = document.createElement('button'); submit.innerText = 'Submit'; form.append(submit); this.validateForm = () => { if (login.getValue() == '' || password.getValue() == '') { submit.disabled = true; } else { submit.disabled = false; if (this.onValidForm) { this.onValidForm(); } } } submit.addEventListener('click', (e) => { e.preventDefault(); if (this.onSubmitForm) { this.onSubmitForm(); } }); this.getLoginValue = () => { return login.getValue(); } this.setLoginValue = (value) => { login.setValue(value); } this.getPasswordValue = () => { return password.getValue(); } this.setPasswordValue = (value) => { password.setValue(value); } this.validateForm(); login.onChange = this.validateForm; password.onChange = this.validateForm; } function Login(parent) { let loginInputEl = document.createElement('input'); loginInputEl.type = 'text'; parent.append(loginInputEl); loginInputEl.addEventListener('input', (event) => { if (this.onChange) { this.onChange(); } }); this.setValue = (value) => { loginInputEl.value = value; } this.getValue = () => { return loginInputEl.value; } } function Password(parent, open) { let passInputEl = document.createElement('input'); parent.append(passInputEl); let passVisibilityCheckboxEl = document.createElement('input'); passVisibilityCheckboxEl.type = 'checkbox'; passVisibilityCheckboxEl.checked = open; parent.append(passVisibilityCheckboxEl); if (open) { passInputEl.type = 'text'; } else { passInputEl.type = 'password'; } passVisibilityCheckboxEl.addEventListener('change', (event) => { if (event.currentTarget.checked) { passInputEl.type = 'text'; } else { passInputEl.type = 'password'; } this.onOpenChange(event.currentTarget.checked); }); passInputEl.addEventListener('input', (event) => { if (this.onChange) { this.onChange(); } }); this.setValue = (value) => { passInputEl.value = value; } this.getValue = () => { return passInputEl.value; } this.setOpen = (value) => { passVisibilityCheckboxEl.checked = value; } this.getOpen = () => { return passVisibilityCheckboxEl.checked; } } function loginPromise(parent) { function executor(resolve, reject) { const form = new LoginForm(parent); form.onSubmitForm = () => resolve({ login: form.getLoginValue(), password: form.getPasswordValue(), }); } return new Promise(executor); } loginPromise(document.body).then(({ login, password }) => console.log(`Вы ввели ${login} и ${password}`)); }