skip to Main Content

Goal: Delay execution of function by at least 1 second.

The problem: Instead of a minimum 1 second delay the do / while loops forever.

The steps:

  • After 1 second timer is set to timerLength.
  • If the fetch request takes more than 1 second no further delay is added.
  • If the fetch request takes less than 1 second further execution will be delayed by up to 1 second by do / while loop.
let timer = 0;
const timerLength = 1000;
    
setTimeout( () => {
    timer = timerLength;
}, timerLength); 
    
// fetch request and other code here... 
    
do {  } while(timer !== timerLength); // no code inside do while
    
// Code after this point is expected to run after a minimum delay of 1 second after setTimeout.

2

Answers


  1. If you need to wait for two or more operations to complete before continuing, you need to use promises.

    In your case, create a promise for your timeout, and use the promise returned by fetch. Pass these to promises to a Promise.all() so that Promise.all() only resolves when both your original promises resolve.

    E.g.

    <script>
        "use strict";
    
        // set timeout promise. Resolves after 1000 milliseconds
        const promise1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve();
            }, 1000);
        });
    
        // Fetch something. May take longer than a second. Resolves when data is returned.
        const promise2 = fetch("http://some/url/somewhere.php");
    
        // Wait until all promises in the array resolve
        Promise.all([promise1, promise2]).then(()=>{alert ("All Done.");});
    </script>
    
    Login or Signup to reply.
  2. The steps you outlined will not run in that order because setTimeout() (and fetch() although you removed that using comment syntax) is asynchronous.

    Asynchronous functions are not run on the Call Stack but are removed and handled differently. Their results are placed on a Task Queue leaving the Call Stack free to run synchronous code.

    The Event Loop keeps checking from time to time for a perfect time to take the first callback from the Task Queue and execute it but since you kept the Event Loop busy with an infinite loop, it will never be free to do these other things.

    do {  } while(timer !== timerLength);
    /* The above runs forever because
    timer !== timerLength will never become false
    Since setTimeout hasn’t run. */

    Use an async function to run asynchronous code and await their result.

    Take a deep dive into the Javascript Event Loop [MDN] and how to write asynchronous code [MDN].

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search