//fetch basic
fetch('https://swapi.dev/api/people/1/')
    .then(res => res.json())
    .then((data, parent = document.body) => {
        let table = document.createElement("table");
        for (let key in data) {
            let tr = document.createElement("tr");
            let td1 = document.createElement("td");
            let td2 = document.createElement("td");

            td1.innerText = key;
            td2.innerText = data[key];

            tr.append(td1);
            tr.append(td2)

            table.append(tr)
        }
        parent.append(table)
    }
    )

//fetch improved
let showData = (data, parent = document.body) => {
    let table = document.createElement("table");

    for (let key in data) {
        let tr = document.createElement("tr");
        let td1 = document.createElement("td");
        let td2 = document.createElement("td");

        td1.innerText = key;

        if (Array.isArray(data[key]) && (data[key][0] !== undefined && data[key][0].includes("https://swapi.dev/api/"))) {
            for (let j of data[key]) {
                let btn = document.createElement("input");
                btn.type = "button";
                btn.value = "LOOK";
                td2.append(btn)

                btn.onclick = e => {
                    table.remove();
                    fetch(j)
                        .then(res => res.json())
                        .then(json => showData(json))
                }
            }
        } else if (typeof data[key] === "string" && data[key].includes("https://swapi.dev/api/")) {
            let btn = document.createElement("input");
            btn.type = "button";
            btn.value = "LOOK";
            td2.append(btn)

            btn.onclick = e => {
                table.remove()
                fetch(data[key])
                    .then(res => res.json())
                    .then(json => showData(json))
            }
        } else {
            td2.innerText = data[key];
        }
        tr.append(td1);
        tr.append(td2)
        table.append(tr)
    }
    parent.append(table)
}

fetch('https://swapi.dev/api/people/1/')
    .then(res => res.json())
    .then(json => showData(json))

//myfetch
let myfetch = url => {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();

        xhr.open("GET", url, true)
        xhr.send()

        xhr.onreadystatechange = () => {
            if (xhr.readyState != 4) return;

            if (xhr.status != 200) {
                let error = new Error(xhr.statusText);
                error.code = xhr.status;
                reject(error);
            } else {
                resolve(JSON.parse(xhr.responseText));
            }
        }
    })
}

myfetch('https://swapi.dev/api/people/1/')
    .then(json => showData(json))

//race
function delay(ms) {
    function executor(ok, fail) {
        setTimeout(() => ok(ms), ms)
    }
    let p = new Promise(executor)
    return p
}

Promise.race([myfetch('https://swapi.dev/api/people/1/'), delay(268)]).then(first => console.log(first))