Synchronous delay in code execution

前端 未结 10 1178
长情又很酷
长情又很酷 2020-12-03 02:29

I have a code which needs to be executed after some delay say 5000 ms.Currently I am using setTimeout but it is asynchronous and i want the execution to wait for its return.

相关标签:
10条回答
  • 2020-12-03 03:15

    Variation on the accepted answer which is just as good as this one.

    Also, I agree with the caveats of preferring setTimeout and asynchronous function calling but sometimes e.g., when building tests, you just need a synchronous wait command...

    function wait(ms) {
        var start = Date.now(),
            now = start;
        while (now - start < ms) {
          now = Date.now();
        }
    }
    

    if you want it in seconds, divide start ms by 1000 on the while check...

    0 讨论(0)
  • 2020-12-03 03:19

    Synchronous wait (only for testing!):

    const syncWait = ms => {
        const end = Date.now() + ms
        while (Date.now() < end) continue
    }
    

    Usage:

    console.log('one')
    syncWait(5000)
    console.log('two')
    

    Asynchronous wait:

    const asyncWait = ms => new Promise(resolve => setTimeout(resolve, ms))
    

    Usage:

    (async () => {
        console.log('one')
        await asyncWait(5000)
        console.log('two')
    })()
    

    Alternative (asynchronous):

    const delayedCall = (array, ms) =>
        array.forEach((func, index) => setTimeout(func, index * ms))
    

    Usage:

    delayedCall([
        () => console.log('one'),
        () => console.log('two'),
        () => console.log('three'),
    ], 5000)
    
    0 讨论(0)
  • 2020-12-03 03:21

    Non-timeout loops (that check the time or count to 1000000 or whatever) just lock up the browser. setTimeout (or the $.doTimeout plugin) is the best way to do it.

    Creating timeouts within a loop won't work because the loop doesn't wait for the previous timeout to occur before continuing, as you've discovered. Try something more like this:

    // Generic function to execute a callback a given number
    // of times with a given delay between each execution
    function timeoutLoop(fn, reps, delay) {
      if (reps > 0)
        setTimeout(function() {
                     fn();
                     timeoutLoop(fn, reps-1, delay);
                   }, delay);
    }
    
    // pass your function as callback
    timeoutLoop(function() { alert("Hi"); },
                5,
                5000);
    

    (I just cobbled this together quickly, so although I'm confident that it works it could be improved in several ways, e.g., within the "loop" it could pass an index value into the callback function so that your own code knows which iteration it is up to. But hopefully it will get you started.)

    0 讨论(0)
  • 2020-12-03 03:24

    Solution using function generators. To show that it can be done. Not recommended.

    function wait(miliseconds){
    
      const gen = function * (){
         const end = Date.now() + miliseconds;
         while(Date.now() < end){yield};
         return;
      }
      
      const iter = gen();
      while(iter.next().done === false);
    }
    
    
    console.log("done 0");
    wait(1000);
    console.log("done 1");
    wait(2000);
    console.log("done 2");

    0 讨论(0)
提交回复
热议问题