简体   繁体   English

如何在按钮提交时连续制作 addEventListener 流

[英]How to make addEventListener stream continuously on button submit

I am trying to stream a list of json objects from my servers endpoint to my frontend using javascript and html.我正在尝试使用 javascript 和 html 将 json 对象列表从我的服务器端点流式传输到我的前端。 Below is my code.下面是我的代码。 Currently addEventListener works fine when I click my form button (HTML also added below for reference).当前,当我单击表单按钮时 addEventListener 工作正常(下面还添加了 HTML 以供参考)。 Heres my problem:这是我的问题:

The list of objects my server endpoint returns is a single list which is continuously having objects appended to the list.我的服务器端点返回的对象列表是一个单独的列表,它不断地将对象附加到列表中。 So I want my front end to refresh automatically every second to show the latest version.所以我希望我的前端每秒自动刷新以显示最新版本。 And so I am finding a way for my addEventListener to rerun the function each time after clearing the HTML it is pushing.因此,我正在为我的 addEventListener 每次清除它正在推送的 HTML 后重新运行该函数找到一种方法。 Currently, I have to click on my button to achieve that and the previously pushed HTML is not getting cleared either.目前,我必须点击我的按钮才能实现这一点,并且之前推送的 HTML 也没有被清除。 So each time I click on the button, I am getting all the existing HTML displayed as many times as I have clicked the button (old versions) plus the latest version of my endpoint data.因此,每次单击该按钮时,都会显示所有现有 HTML 显示的次数与单击该按钮(旧版本)以及端点数据的最新版本一样多。

The solution I want to achieve is to be able to click on my start stream button once, and have the function run every X seconds after clearing the older data each time to only show the latest list returned by fetch.我想要实现的解决方案是能够单击我的开始流按钮一次,并在每次清除旧数据后每 X 秒运行一次该功能,以仅显示 fetch 返回的最新列表。

 const startStream = document.querySelector('form') const messageOne = document.querySelector('#message-1') startStream.addEventListener('submit', (e) => { e.preventDefault() messageOne.textContent = 'Streaming...' function fetchData() { fetch('http://localhost:1337/dashboard') .then(response => { if (!response.ok) { throw Error('ERROR') } response.json().then(events => { events.forEach(event => { const html = `<div class="event"> Event: ${event.name} </div> ` let div = document.createElement('div'); div.setAttribute("id", "app"); div.innerHTML = html; document.body.appendChild(div); }) }) .catch(error => { console.log(error) }) }) } fetchData() });
 <h1>Dashboard</h1> <form> <button>Start Stream</button> </form> <p id="message-1"></p>

Is the question just how to run a function every X seconds?问题是如何每 X 秒运行一个函数? If so, the function you're looking for is setInterval , which is like setTimeout but it continues running over and over.如果是这样,您正在寻找的函数是setInterval ,它类似于setTimeout但它会一遍又一遍地继续运行。 For example:例如:

setInterval( () => console.log("hello"), 100 )

will log "hello" once every 100ms将每 100 毫秒记录一次“hello”

This is a detailed example but try this approach it may work for you any corrections will be great :这是一个详细的示例,但请尝试这种方法,它可能对您有用,任何更正都会很棒

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Repeating Event example</title>
</head>

<body>
    <div>
        <button id="start-stream-btn">Start Streaming</button>
        <p id="message-section"></p>
        <div id="app-data-div"></div>
    </div>
    <script>
        window.onload = function () {
            var streamButton = document.getElementById("start-stream-btn");
            var messageContainer = document.getElementById("message-section");
            var appDataContainer = document.getElementById("app-data-div");

            function handleFetchError(appDataContainerRef, messageContainerRef) {
                messageContainerRef.innerText = "There was an Error fetching data!";
                // optional clear previous data or leave it by commenting the line below
                appDataContainerRef.innerHTML = "";
            }
            // Define the function that fetches our data
            function fetchData(appDataContainerRef, messageContainerRef, timerRef) {
                fetch('http://localhost:1337/dashboard')
                    .then(response => {
                        if (!response.ok) {
                            throw Error('ERROR')
                        }
                        response.json().then(events => {
                            events.forEach(event => {
                                // Create your string here with a loop
                                const htmlString = `<div class="event">
                                    Event: ${event.name}
                                    </div>`;
                                // Set your string here - replacing any previous
                                appDataContainerRef.innerHTML = htmlString;
                            })
                        })
                            .catch(error => {
                                console.log(error);
                                handleFetchError(appDataContainerRef, messageContainerRef);
                                // optional clear timer on error, you can comment this out if you want the timer to continue
                                clearInterval(timerRef);
                            });
                    }).catch(error => {
                        console.log(error);
                        handleFetchError(appDataContainerRef, messageContainerRef);
                        // optional clear timer on error, you can comment this out if you want the timer to continue
                        clearInterval(timerRef);
                    });
            }
            var timerRef;
            // Attach event listener to your button
            streamButton.addEventListener("click", function (e) {
                e.preventDefault(); //if it is in a form or if you have any form on your current page
                messageContainer.innerText = "Streaming...";
                timerRef = setInterval(function () {
                    // check and clear your timer before adding another timer here on click
                    if (!!timerRef) clearInterval(timerRef);
                    fetchData(appDataContainer, messageContainer, timerRef);
                }, 1000); // X seconds intervals i.e. for now 1s = 1000ms
            });

        }
    </script>
</body>

</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM