Загрузка данных


<!DOCTYPE html>
<html lang="ru">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Работа Promise</title>

    <style>

        * {
            box-sizing: border-box;
        }

        body {
            margin: 0;
            min-height: 100vh;
            padding: 35px;

            font-family: Arial, sans-serif;

            background-color: #f3f1f1;
            color: #222;
        }

        .container {
            width: min(1100px, 100%);
            margin: 0 auto;
        }

        h1 {
            margin: 0 0 25px;
            text-align: center;
            font-size: 34px;
        }


        /* Верхний блок */

        .explanation {
            background-color: rgb(190, 193, 193);

            padding: 28px;

            border-radius: 16px;

            box-shadow:
                0 8px 25px rgba(0, 0, 0, 0.10);

            margin-bottom: 35px;
        }

        .explanation h2 {
            margin: 0 0 10px;
        }

        .explanation > p {
            margin: 0;

            line-height: 1.5;

            color: #3d3d3d;
        }


        /* Состояния */

        .states {
            display: flex;
            gap: 15px;
            margin-top: 25px;
        }

        .state {
            flex: 1;

            padding: 24px;

            text-align: center;

            border-radius: 12px;

            color: #1d1d1d;

            transition:
                transform 0.2s ease,
                box-shadow 0.2s ease;
        }

        .state:hover {
            transform: translateY(-3px);

            box-shadow:
                0 8px 18px rgba(0, 0, 0, 0.14);
        }

        .state h3 {
            margin: 0 0 8px;
            font-size: 20px;
        }

        .state p {
            margin: 0;
            color: #252525;
        }

        .pending {
            background-color: rgb(129, 86, 86);
        }

        .fulfilled {
            background-color: #a76b73;
        }

        .rejected {
            background-color: rgb(136, 60, 66);
        }


        /* Окна демо */

        .demo-window {
            padding: 26px;

            background-color: #e8e5e5;

            border: 1px solid rgba(129, 86, 86, 0.22);

            border-radius: 18px;

            box-shadow:
                0 12px 35px rgba(0, 0, 0, 0.10);

            margin-bottom: 30px;
        }

        .demo-header {
            margin-bottom: 18px;

            padding-bottom: 16px;

            border-bottom:
                1px solid rgba(129, 86, 86, 0.20);
        }

        .demo-header h2 {
            margin: 0;
            font-size: 23px;
        }


        /* Визуальные Promise */

        .promise-visual {
            display: flex;

            flex-direction: column;

            gap: 10px;

            margin-bottom: 18px;
        }

        .promise-item {
            display: flex;

            align-items: center;
            justify-content: space-between;

            padding: 14px 18px;

            background-color: #d8d4d4;

            border-radius: 10px;

            font-size: 15px;
            font-weight: 600;

            transition:
                background-color 0.3s ease,
                transform 0.3s ease;
        }

        .promise-item.pending-item {
            background-color: rgb(129, 86, 86);
        }

        .promise-item.fulfilled-item {
            background-color: #a76b73;
        }

        .promise-item.rejected-item {
            background-color: rgb(136, 60, 66);
        }

        .promise-state {
            padding: 5px 10px;

            background-color: rgba(255, 255, 255, 0.25);

            border-radius: 15px;

            font-size: 13px;
        }


        /* Обе консоли одинаковые */

        .console {
            height: 220px;

            padding: 22px;

            overflow-y: auto;

            background-color: #252525;

            color: white;

            border-radius: 12px;

            font-family: Consolas, monospace;

            font-size: 15px;

            line-height: 1.6;

            box-shadow:
                inset 0 0 0 1px rgba(255, 255, 255, 0.04),
                0 8px 20px rgba(0, 0, 0, 0.14);
        }

        .console::-webkit-scrollbar {
            width: 8px;
        }

        .console::-webkit-scrollbar-thumb {
            background-color: rgb(129, 86, 86);
            border-radius: 10px;
        }


        /* Кнопки */

        .demo-area {
            display: flex;

            gap: 12px;

            margin-top: 18px;

            flex-wrap: wrap;
        }

        button {
            padding: 12px 24px;

            border: none;
            outline: none;

            border-radius: 9px;

            font-size: 15px;
            font-weight: 600;

            cursor: pointer;

            transition:
                transform 0.15s ease,
                background-color 0.25s ease,
                box-shadow 0.25s ease;

            user-select: none;
        }


        #createPromise,
        #runSuccess {
            background-color: #a76b73;

            color: #1d1d1d;

            box-shadow:
                0 5px 14px rgba(129, 86, 86, 0.25);
        }

        #createPromise:hover,
        #runSuccess:hover {
            background-color: rgb(187, 102, 102);

            transform: translateY(-2px);

            box-shadow:
                0 8px 18px rgba(129, 86, 86, 0.35);
        }


        #runError {
            background-color: rgb(136, 60, 66);

            color: #1d1d1d;

            box-shadow:
                0 5px 14px rgba(129, 86, 86, 0.25);
        }

        #runError:hover {
            background-color: rgb(187, 102, 102);

            transform: translateY(-2px);

            box-shadow:
                0 8px 18px rgba(129, 86, 86, 0.35);
        }


        #clearConsole,
        #clearConsole2 {
            background-color: #d8d4d4;

            color: #222;
        }

        #clearConsole:hover,
        #clearConsole2:hover {
            background-color: rgb(129, 86, 86);

            transform: translateY(-2px);

            box-shadow:
                0 7px 16px rgba(129, 86, 86, 0.25);
        }

        button:active {
            transform: translateY(1px) scale(0.97);
        }


        /* Логи */

        .log-entry {
            margin: 6px 0;
        }

        .info {
            color: #d9b6b9;
        }

        .success {
            color: #d58b91;
        }

        .error {
            color: #a76b73;
        }


        @media (max-width: 700px) {

            body {
                padding: 20px;
            }

            .states {
                flex-direction: column;
            }

            .demo-area {
                flex-direction: column;
            }

            button {
                width: 100%;
            }
        }

    </style>

</head>


<body>

<div class="container">

    <h1>Promise в JS</h1>


    <div class="explanation">

        <h2>Что такое Promise?</h2>

        <p>
            Promise (с англ. «обещание») в JavaScript —
            это специальный объект, который представляет
            результат асинхронной операции.
        </p>


        <div class="states">

            <div class="state pending">
                <h3>Pending</h3>
                <p>Ожидание</p>
            </div>

            <div class="state fulfilled">
                <h3>Fulfilled</h3>
                <p>Исполнено</p>
            </div>

            <div class="state rejected">
                <h3>Rejected</h3>
                <p>Отклонено</p>
            </div>

        </div>

    </div>



    <!-- ПЕРВАЯ ДЕМКА -->

    <div class="demo-window">

        <div class="demo-header">
            <h2>Демо работы Promise</h2>
        </div>


        <div id="promiseVisual" class="promise-visual"></div>


        <div id="console" class="console"></div>


        <div class="demo-area">

            <button id="createPromise">
                Создать Promise
            </button>

            <button id="clearConsole">
                Очистить консоль
            </button>

        </div>

    </div>



    <!-- ВТОРАЯ ДЕМКА -->

    <div class="demo-window">

        <div class="demo-header">
            <h2>Basic Promise</h2>
        </div>


        <div id="basicConsole" class="console"></div>


        <div class="demo-area">

            <button id="runSuccess">
                Запустить успешно
            </button>

            <button id="runError">
                Запустить с ошибкой
            </button>

            <button id="clearConsole2">
                Очистить консоль
            </button>

        </div>

    </div>

</div>



<script>

    /* =====================================
       ПЕРВАЯ ДЕМКА
    ===================================== */


    const consoleBlock =
        document.getElementById('console');


    const promiseVisual =
        document.getElementById('promiseVisual');


    let promiseCounter = 0;


    const createPromiseButton =
        document.getElementById('createPromise');


    const clearConsoleButton =
        document.getElementById('clearConsole');



    function addLog(message, type = 'info') {

        const logEntry =
            document.createElement('div');


        logEntry.className =
            `log-entry ${type}`;


        logEntry.textContent =
            `> ${message}`;


        consoleBlock.appendChild(logEntry);


        consoleBlock.scrollTop =
            consoleBlock.scrollHeight;
    }



    createPromiseButton.addEventListener(
        'click',

        function () {

            promiseCounter++;


            const currentPromise =
                promiseCounter;


            const promiseItem =
                document.createElement('div');


            promiseItem.className =
                'promise-item pending-item';


            promiseItem.innerHTML = `
                <span>Promise #${currentPromise}</span>
                <span class="promise-state">Pending</span>
            `;


            promiseVisual.appendChild(
                promiseItem
            );


            const stateText =
                promiseItem.querySelector(
                    '.promise-state'
                );


            addLog(
                `Promise #${currentPromise} created`
            );


            addLog(
                `Promise #${currentPromise}: Pending`
            );



            const promise =
                new Promise((resolve, reject) => {


                    setTimeout(() => {


                        const success =
                            Math.random() > 0.5;


                        if (success) {

                            resolve('Success');

                        } else {

                            reject(
                                'Promise failed with error'
                            );

                        }


                    }, 2000);


                });



            promise

                .then(function (result) {


                    promiseItem.className =
                        'promise-item fulfilled-item';


                    stateText.textContent =
                        'Fulfilled';


                    addLog(
                        `Promise #${currentPromise}: Fulfilled`,
                        'success'
                    );


                    addLog(
                        result,
                        'success'
                    );


                })


                .catch(function (error) {


                    promiseItem.className =
                        'promise-item rejected-item';


                    stateText.textContent =
                        'Rejected';


                    addLog(
                        `Promise #${currentPromise}: Rejected`,
                        'error'
                    );


                    addLog(
                        error,
                        'error'
                    );


                });


        }

    );



    clearConsoleButton.addEventListener(
        'click',

        function () {

            consoleBlock.innerHTML = '';

            promiseVisual.innerHTML = '';

            promiseCounter = 0;

        }

    );



    /* =====================================
       ВТОРАЯ ДЕМКА
    ===================================== */


    function logToConsole(
        message,
        type = 'info',
        consoleId
    ) {

        const consoleElement =
            document.getElementById(consoleId);


        const logEntry =
            document.createElement('div');


        logEntry.className =
            `log-entry ${type}`;


        logEntry.textContent =
            `> ${new Date().toLocaleTimeString()}: ${message}`;


        consoleElement.appendChild(logEntry);


        consoleElement.scrollTop =
            consoleElement.scrollHeight;
    }



    function clearConsole(consoleId) {

        document.getElementById(consoleId).innerHTML = '';

    }



    function createBasicPromise(success = true) {

        return new Promise((resolve, reject) => {


            setTimeout(() => {


                if (success) {

                    resolve('Data is loaded');

                } else {

                    reject('Data loading error');

                }


            }, 2000);


        });

    }



    function runBasicPromise(success) {

        const consoleId =
            'basicConsole';


        clearConsole(consoleId);


        logToConsole(
            'Basic Promise is creating...',
            'info',
            consoleId
        );


        createBasicPromise(success)

            .then(function (result) {

                logToConsole(
                    result,
                    'success',
                    consoleId
                );

            })

            .catch(function (error) {

                logToConsole(
                    error,
                    'error',
                    consoleId
                );

            });

    }



    document
        .getElementById('runSuccess')
        .addEventListener(
            'click',

            function () {

                runBasicPromise(true);

            }
        );



    document
        .getElementById('runError')
        .addEventListener(
            'click',

            function () {

                runBasicPromise(false);

            }
        );



    document
        .getElementById('clearConsole2')
        .addEventListener(
            'click',

            function () {

                clearConsole(
                    'basicConsole'
                );

            }
        );

</script>

</body>

</html>