In node. js a timer is used to time the execution of the function

  • 2020-03-30 03:43:10
  • OfStack

If you're familiar with client-side JavaScript programming, you've probably used the setTimeout and setInterval functions, which allow you to delay running the function for a while. For example, the following code, once loaded into the Web page, appends "Hello there" to the page document after 1 second:


var oneSecond = 1000 * 1; // one second = 1000 x 1 ms setTimeout(function() {     document.write('<p>Hello there.</p>'); }, oneSecond);

SetInterval, on the other hand, allows functions to be executed repeatedly at specified intervals. If you inject the following code into a Web page, it will cause a "Hello there" to be appended to the page document every second:


                  var oneSecond = 1000 * 1; // one second = 1000 x 1 ms                   setInterval(function() {                                     document.write('<p>Hello there.</p>');                   }, oneSecond);

Because the Web has long been a platform for building applications, rather than simply static pages, such requirements are emerging. These task scheduling functions help developers implement regular form validation, delay remote data synchronization, or UI interactions that require a delayed response. Node also implements these methods in their entirety. On the server side, you can use them to repeat or delay many tasks, such as cache expiration, connection pool cleanup, session expiration, polling, and so on.

Delay function execution with setTimeout

SetTimeout can create an execution plan to run the specified function once in the future, for example:


                   var timeout_ms = 2000; // 2 seconds                    var timeout = setTimeout(function() {                             console.log("timed out!");                    }, timeout_ms);

Just like client-side JavaScript, setTimeout takes two arguments, the first for the function to be delayed and the second for the delay time in milliseconds.

SetTimeout returns an internal object that can be used as an argument to call clearTimeout to cancel the timer.

Cancel the execution plan using clearTimeout

Once you have the timeout handle, you can use clearTimeout to cancel the function execution plan, like this:


                   var timeoutTime = 1000; // one second                    var timeout = setTimeout(function() {                             console.log("timed out!");                    }, timeoutTime);                    clearTimeout(timeout);

  In this example, the timer will never be triggered and "time out!" will never be output. The words. You can also cancel the execution plan at any time in the future, as in the following example:


 var timeout = setTimeout(function A() {
 
                            console.log("timed out!");
 
                   }, 2000);
 
                   setTimeout(function B() {
 
                            clearTimeout(timeout);
 
                   }, 1000);

The code specifies two delayed functions, A and B, with function A scheduled to execute after 2 seconds and plan B scheduled to execute after 1 second, because function B executes first, and it cancels the execution plan of A, so A never runs.

Make and cancel the repetitive execution plan for the function

SetInterval is similar to setTimeout, but it repeats a function at a specified interval. You can use it to periodically trigger a program to do things like clean up, collect, log, get data, poll, and so on.

The following code outputs a "tick" to the console every second:


                   var period = 1000; // 1 second                    setInterval(function() {                             console.log("tick");                    }, period);

If you don't want it to run forever, cancel the timer with clearInterval().

SetInterval returns an execution plan handle that can be used as an argument to clearInterval to cancel the execution plan:


                   var interval = setInterval(function() {                             console.log("tick");                    }, 1000);                    // ...                    clearInterval(interval);

Use process.nexttick to delay function execution to the next round of the event loop

Sometimes the client-side JavaScript programmer USES setTimeout(callback,0) to delay the task for a short time. The second parameter is 0 milliseconds, which tells the JavaScript runtime to execute the callback function as soon as all pending events are processed. Sometimes this technique is used to delay operations that do not need to be performed immediately. For example, sometimes you need to wait until the user event has been processed before playing the animation or doing some other calculations.

In Node, which literally means "event loop," the event loop runs in a loop that handles the event queue, and each round of the event loop is called a tick.

You can call the callback function every time the event loop starts the next round (the nextTick) execution, which is exactly how process.nexttick works, and setTimeout, setTimeout USES the internal execution queue of the JavaScript runtime instead of the event loop.

By using process.nexttick (callback) instead of setTimeout(callback, 0), your callback function executes immediately after the events in the queue are processed, much faster than the JavaScript timeout queue (in terms of CPU time).

You can delay the function until the next round of the event loop, as follows:


                   process.nextTick(function() {                             my_expensive_computation_function();                    });

  Note: the process object is one of the few global objects in Node.

Blocking event cycle

The Node and JavaScript runtime USES a single-threaded loop of events, each time, and the runtime processes the next event in the queue by calling the relevant callback function. When the event completes, the event loop takes the result of the execution and processes the next event, and so on, until the event queue is empty. If one of the callbacks takes a long time to run, the event loop cannot handle the other pending events during that time, which makes the application or service very slow.

When processing events, using memory-sensitive or processor-sensitive functions can cause the event loop to slow down and cause a large number of events to pile up, not be processed in time, or even block the queue.

See the following example of blocking the event loop:


                   process.nextTick(function nextTick1() {                             var a = 0;                             while(true) {                                      a ++;                             }                    });                    process.nextTick(function nextTick2() {                             console.log("next tick");                    });                    setTimeout(function timeout() {                             console.log("timeout");                    }, 1000);

In this example, the nextTick2 and timeout functions have no chance to run no matter how long they wait, because the event loop is blocked by the infinite loop in the nextTick function, even though the timeout function is scheduled to execute after 1 second.

                When using setTimeout, callback functions are added to the execution plan queue, and in this case they are not even added to the queue. This is an extreme example, but you can see that running a processor-sensitive task can block or slow down the event loop.

Exit the event loop

With process.nexttick, you can defer a non-critical task until the next round of the event loop (tick), freeing the event loop to continue executing other pending events.

For example, if you want to delete a temporary file, but you don't want the data event callback to wait for the IO operation, you can delay it by:


                   stream.on("data", function(data) {                             stream.end("my response");                             process.nextTick(function() {                                      fs.unlink("/path/to/file");                             });                    });

Replace the setInterval with setTimeout to ensure the serialization of function execution

Suppose you're going to design a function called my_async_function that does certain I/O operations (like parsing log files) and wants it to execute periodically. You can do this with setInterval:


                   var interval = 1000;                    setInterval(function() {                             my_async_function(function() {                                      console.log('my_async_function finished!');                             });                    },interval);//Translator's note: I added "interval" earlier, the author should have missed
by a clerical error

You have to be able to make sure that these functions are not executed at the same time, but you can't make sure that if you use setinterval, if the my_async_function function is running a millisecond longer than the interval variable, they will be executed at the same time instead of sequentially.

Translator's note :(the following bold text is added by the translator, not the original text)

In order to understand this part of the content, you can modify the author's code so that it can actually run:


                   var interval = 1000;                    setInterval(function(){                             (function my_async_function(){                                       setTimeout(function(){                                               console.log("1");                                       },5000);                            })();                    },interval);

  If you run this code, you will see that after waiting for 5 seconds, "hello" is printed every 1 second. The expectation is that after the current my_async_function completes (5 seconds), wait 1 second to execute the next my_async_function, with 6 seconds between each output. The reason for this is that my_async_function is not executed sequentially, but multiple runs at the same time.

  Therefore, you need a way to force the interval between the end of one my_async_function and the start of the next my_async_function is exactly the time specified by the interval variable. You can do this:
 


                    var interval = 1000; //1 second                    (function schedule() {      //Line 3                             setTimeout(function do_it() {                                      my_async_function(function() {      //Line 5                                                console.log('async is done!');                                                schedule();                                      });                             }, interval);                    }());        //Line 10
 

In the previous code, you declared a function called schedule (line 3) and called it immediately after the declaration (line 10). The schedule function runs the do_it function after 1 second (specified by interval). After 1 second, line 5 my_async_function is called, and when it's finished, it calls its own anonymous callback function (line 6), which in turn resets do_it's execution schedule again, allowing it to execute again after 1 second, and the code begins to loop serially.

summary

You can use the setTimeout() function to pre-set the execution plan for the function and cancel it with the clearTimeout() function. You can also periodically repeat a function with setInterval() and, in turn, cancel the repeat plan with clearInterval().

If the event loop is blocked because a processor-sensitive operation is used, the functions that were supposed to be executed will be delayed or never executed. So do not use cpu-sensitive operations within the event loop. Also, you can use process.nexttick () to delay the execution of functions until the next round of the event loop.

When I/O is used with setInterval(), there is no guarantee that there will be only one pending call at any point in time, but you can use recursive functions and setTimeout() to get around this tricky problem.


Related articles: