0

I'm trying to create a loop that isn't breaking my browser. This loop should get information from a SQL database every 10 seconds. So I tried this in JavaScript:

while(true) {
    setTimeout(doRequest(), 10000);
}

but it's just freezing the browser because it starts before the page is ready. I tried window.onload, document.onload and also $(document).ready() but nothing worked. There was always the error: document.onload is not a function.
Then I read about the Web Worker, but that didn't work either. So I decided to use PHP instead:
JavaScript:

function test () {
    $.post(
        "../../modules/communicator.php",
        {
            action: "test"
        },
        function(result) {
            console.log(window.location.href);
        }
    );
}

communicator.php:

if ($_POST['action'] == 'test') {
    echo("test");
    sleep(5);
    echo("hello");
}

but it returns testhello after 5 seconds.

Is there a way to return a string, wait 5 seconds, and then return the next one?

  • 4
    You need `setInterval(doRequest, 10000);` (and remove the while loop). You were calling the function hundreds of thousands of times in the first second. –  Jan 30 '20 at 09:20
  • 2
    As for the 2nd part, first PHP finishes, *then* the result is sent back to the browser. –  Jan 30 '20 at 09:22
  • 3
    A setTimeout within a loop will not delay the loop. You just create an infinite number of setTimeouts that all fire 10 seconds later. – Turnip Jan 30 '20 at 09:24
  • 2
    Also note that AJAX polling is an anti-pattern as it doesn't scale and causes server performance issues. If you need to keep the UI in sync with state changes on the server, use Websockets instead. – Rory McCrossan Jan 30 '20 at 09:26
  • In non-ajax scenarios, you can also use PHP output buffering to achieve this kind of effect, but it's a bit crude. Sounds like websockets might be more appropriate for your scenario, although it's such a simplistic example given that we don't really know what the real goal is that you're trying to get to. – ADyson Jan 30 '20 at 09:37
  • How are you telling the database you want the *next* thing, or are you really just asking it to give you an updated response to the same query (e.g. `SELECT * FROM table`) each time? If that's the case, you just need the PHP script to fetch the response from the database as and when requested (and echo it out as a JSON probably)... all you need to work out then is how to poll that PHP script regularly. – CD001 Jan 30 '20 at 09:38
  • @CD001 I just want an updated response of the database every 5 or 10 seconds. The regular fetching is the problem. I tried ```setInterval``` like @Chris G said. But whyever, it's just calling the script one time. –  Jan 30 '20 at 09:50
  • 1
    Here's an [example](https://stackoverflow.com/questions/6835835/jquery-simple-polling-example) of Ajax polling that might be worth a look - odds are you'd probably be better off with a websockets tutorial mind. – CD001 Jan 30 '20 at 10:12
  • _"I tried setInterval like @Chris G said. But whyever, it's just calling the script one time."_ ....that shouldn't be the case if you did it correctly. `setInterval(test, 10000);` should do the trick. Take care you write `test` not `test()` though - with `()` you're telling it to execute the function _now_, and then run the _result_ of the function at intervals, which clearly makes no sense. That mistake could be the cause of it only executing once. But by saying `test` instead you're passing a _reference to the function_ to be executed later. – ADyson Jan 30 '20 at 11:50
  • BTW every 10 seconds is actually very frequent and could overload the server if the query takes longer than usual, or lots of people are running it at once. Does the data in your table really get updated as frequently as that, and does the user really need to see it quite so instantly? Would they be unable to work properly if they didn't see it instantly?? If that's really the scenario, then use websockets instead of AJAX. If it's actually not as urgent as that in real life, then you can carry on using AJAX and setInterval, but maybe reduce it to once every minute, or even less. – ADyson Jan 30 '20 at 11:52

1 Answers1

1

Thank you all! I fixed it! setInterval(doRequest, 10000);