setTimeout in Node.js loop

后端 未结 8 1576
眼角桃花
眼角桃花 2020-12-06 05:16

I\'m a bit confused as to how setTimeout works. I\'m trying to have a setTimeout in a loop, so that the loop iterations are, say, 1s apart. Each l

相关标签:
8条回答
  • 2020-12-06 05:53

    You need something like this

    var counter = 5;
    
    function makeRequst(options, i) {
        // do your request here
    }
    
    function myFunction() {
        alert(counter);
    
        // create options object here
        //var options = {
        //    host:'www.host.com',
        //    path:'/path/'+counter
        //};
        //makeRequest(options, counter);
    
        counter--;
        if (counter > 0) {
            setTimeout(myFunction, 1000);    
        }
    }
    

    See also this fiddle

    At the point of the alert(count); you can do your call to the server. Note that the counter works opposite (counting down). I updated with some comments where to do your thing.

    0 讨论(0)
  • 2020-12-06 05:53

    setTimeout is non blocking, it is asynchronous. You give it a callback and when the delay is over, your callback is called.

    Here are some implementations:

    Using recursion

    You can use a recursive call in the setTimeout callback.

    function waitAndDo(times) {
      if(times < 1) {
        return;
      }
    
      setTimeout(function() {
    
        // Do something here
        console.log('Doing a request');
    
        waitAndDo(times-1);
      }, 1000);
    }
    

    Here is how to use your function:

    waitAndDo(2000); // Do it 2000 times
    

    About stack overflow errors: setTimeout clear the call stack (see this question) so you don't have to worry about stack overflow on setTimeout recursive calls.

    Using generators (io.js, ES6)

    If you are already using io.js (the "next" Node.js that uses ES6) you can solve your problem without recursion with an elegant solution:

    function* waitAndDo(times) {
      for(var i=0; i<times; i++) {
    
        // Sleep
        yield function(callback) {
          setTimeout(callback, 1000);
        }    
    
        // Do something here
        console.log('Doing a request');
      }
    }
    

    Here is how to use your function (with co):

    var co = require('co');
    
    co(function* () {
      yield waitAndDo(10);
    });
    

    BTW: This is really using a loop ;)

    Generator functions documentation.

    0 讨论(0)
  • 2020-12-06 05:55

    You're calling makeRequest() in your setTimeout call - you should be passing the function to setTimeout, not calling it, so something like

    setTimeout(makeRequest, 1000);
    

    without the ()

    0 讨论(0)
  • 2020-12-06 05:57

    Right now you're scheduling all of your requests to happen at the same time, just a second after the script runs. You'll need to do something like the following:

    var numRequests = 2000,
        cur = 1;
    
    function scheduleRequest() {
        if (cur > numRequests) return;
    
        makeRequest({
            host: 'www.host.com',
            path: '/path/' + cur
        }, cur);
    
        cur++;
        setTimeout(scheduleRequest, 1000)
    }
    

    Note that each subsequent request is only scheduled after the current one completes.

    0 讨论(0)
  • 2020-12-06 05:58
            let i = 20;
            let p = Promise.resolve(i)
            while (i > 0) {
            (i => {
                p = p.then(() => {
                return new Promise(function (resolve, reject) {
                    setTimeout(function () {
                        console.log(i);
                    resolve()
                    }, 2000)
                })
                })
            })(i)
            i--
            }
            p = p.then(data => console.log('execution ends'))
    
    0 讨论(0)
  • 2020-12-06 06:09

    I'm surprised that no one has mentioned this above, but it sounds like you need setInterval not setTimeout.

    vat poller = setInterval(makeRequestFunc, 3000)
    

    The code above will make a request every 3 seconds. Since you saved the object to the variable poller, you can stop polling by clearing the object like so:

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