//fetch basic + improved fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then(luke => swapiTable(document.body, luke)) function swapiTable(parent, data) { let table = document.createElement("table") table.border = 1 table.style.borderColor = 'purple' parent.append(table) for (let key in data) { let tr = document.createElement("tr") table.append(tr) let th = document.createElement("th") tr.append(th) th.append(key) let td = document.createElement("td") tr.append(td) let btn = function(parent, link) { button = document.createElement("button") button.append(link) button.style.background = "#8B008B" button.style.color = 'white' parent.append(button) button.onclick = () => { fetch(link) .then(res => res.json()) .then(luke => swapiTable(document.body, luke)) } } if (data[key] instanceof Array) { for (let arr of data[key]) { if (arr.startsWith("https://swapi.dev/api/")) { btn(td, arr) } else td.append(data[key]) } }else { if (data[key].startsWith("https://swapi.dev/api/")) { btn(td, data[key]) }else td.append(data[key]) } } } //myfetch function myfetch(url){ return new Promise(function (resolve, reject){ const xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.onload = () => { if (xhr.status != 200) { reject(`Ошибка: ${xhr.statusText}`) return } resolve(JSON.parse(xhr.response)) } xhr.onerror = function() { reject("Error") } xhr.send() }) } myfetch('https://swapi.dev/api/people/1/') .then(luke => console.log(luke)) //race const delay = new Promise((resolve, reject) => { setTimeout(resolve, Math.random() * 100, 'delay'); }); Promise.race([delay , myfetch('https://swapi.dev/api/people/1/')]).then((value) => { console.log(value) })