Node.js中使用计时器定时执行函数详解(3)

你必须能确保这些函数不会被同时执行,但是如果使用setinterval你无法保证这一点,假如my_async_function函数运行的时间比interval变量多了一毫秒,它们就会被同时执行,而不是按次序串行执行。

译者注:(下面粗体部分为译者添加,非原书内容)

为了方便理解这部分内容,可以修改下作者的代码,让它可以实际运行:

复制代码 代码如下:


                   var interval = 1000;

setInterval(function(){

(function my_async_function(){

setTimeout(function(){

console.log("1");

},5000);

})();

},interval);

运行下这段代码看看,你会发现,等待5秒钟后,“hello ”被每隔1秒输出一次。而我们期望是,当前my_async_function执行完毕(耗费5秒)后,等待1秒再执行下一个my_async_function,每次输出之间应该间隔6秒才对。造成这种结果,是因为my_async_function不是串行执行的,而是多个在同时运行。

因此,你需要一种办法来强制使一个my_async_function执行结束到下个my_async_function开始执行之间的间隔时间正好是interval变量指定的时间。你可以这样做:
 

复制代码 代码如下:


                    var interval = 1000; // 1 秒

(function schedule() {      //第3行

setTimeout(function do_it() {

my_async_function(function() {      //第5行

console.log('async is done!');

schedule();

});

}, interval);

}());        //第10行
 

前面代码里,声明了一个叫schedule的函数(第3行),并且在声明后立刻调用它(第10行),schedule函数会在1秒(由interval指定)后运行do_it函数。1秒钟过后,第5行的my_async_function函数会被调用,当它执行完毕后,会调用它自己的那个匿名回调函数(第6行),而这个匿名回调函数又会再次重置do_it的执行计划,让它1秒钟后重新执行,这样代码就开始串行地不断循环执行了。

小结

可以用setTimeout()函数预先设定函数的执行计划,并用clearTimeout()函数取消它。还可以用setInterval()周期性的重复执行某个函数,相应的,可以使用clearInterval()取消这个重复执行计划。

如果因为使用了一个处理器敏感的操作而堵塞了事件循环,那些原计划应该被执行的函数将会被延迟,甚至永远无法执行。所以不要在事件循环内使用CPU敏感的操作。还有,你可以使用process.nextTick()把函数的执行延迟到事件循环的下一轮。

I/O和setInterval()一起使用时,你无法保证在任何时间点只有一个挂起的调用,但是,你可以使用递归函数和setTimeout()函数来回避这个棘手的问题。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgspff.html