Node.js 指南(Node.js中的定时器)

Node.js中的定时器

Node.js中的Timers模块包含在一段时间后执行代码的函数,定时器不须要经过require()导入,由于全部方法均可以在全局范围内模拟浏览器JavaScript API,要彻底了解什么时候执行定时器功能,最好先阅读Node.js事件循环segmentfault

用Node.js控制时间连续性

Node.js API提供了几种调度代码的方法,以便在当前时刻以后的某个时刻执行,下面的函数可能看起来很熟悉,由于它们在大多数浏览器中均可用,但Node.js实际上提供了这些方法的本身的实现,定时器与系统紧密集成,尽管API镜像了浏览器API,但实现方面存在一些差别。浏览器

“我说的时候”执行 ~ setTimeout()

setTimeout()可用于在指定的毫秒数后调度代码执行,此函数相似于浏览器JavaScript API中的window.setTimeout(),可是没法传递一串代码来执行。ide

setTimeout()接受一个函数做为第一个参数执行,毫秒延迟定义为一个数字做为第二个参数,还能够包括其余参数,并将这些参数传递给函数,这是一个例子:函数

function myFunc(arg) {
  console.log(`arg was => ${arg}`);
}

setTimeout(myFunc, 1500, 'funky');

因为调用了setTimeout(),上面的函数myFunc()将尽量接近1500毫秒(或1.5秒)执行。性能

设置的超时间隔不能依赖于在该精确的毫秒数以后执行,这是由于阻塞或保留在事件循环上的其余执行代码将推迟执行超时,惟一的保证是超时不会比声明的超时间隔更早执行。ui

setTimeout()返回一个Timeout对象,该对象可用于引用已设置的超时,此返回的对象可用于取消超时(请参阅下面的clearTimeout())以及更改执行行为(请参阅下面的unref())。this

“在此以后”执行 ~ setImmediate()

setImmediate()将在当前事件循环周期结束时执行代码,此代码将在当前事件循环中的任何I/O操做以后以及为下一个事件循环调度的任何计时器以前执行,这个代码执行能够被认为是“正好在此以后”,这意味着setImmediate()函数调用以后的任何代码都将在setImmediate()函数参数以前执行。code

setImmediate()的第一个参数将是要执行的函数,任何后续参数将在执行时传递给函数,这是一个例子:对象

console.log('before immediate');

setImmediate((arg) => {
  console.log(`executing immediate: ${arg}`);
}, 'so immediate');

console.log('after immediate');

传递给setImmediate()的上述函数将在全部可运行代码执行后执行,控制台输出将为:进程

before immediate
after immediate
executing immediate: so immediate

setImmediate()返回一个Immediate对象,可用于取消已调度的immediate(请参阅下面的clearImmediate())。

注意:不要混淆setImmediate()process.nextTick(),它们有一些主要的不一样之处,第一个是process.nextTick()将在任何设置的Immediate以前以及任何调度的I/O以前运行,第二个是process.nextTick()是不可清除的,意思是一旦代码被安排用process.nextTick()执行,就没法中止执行,就像使用普通函数同样,请参阅本指南以更好地理解process.nextTick()的操做。

“无限循环”执行 ~ setInterval()

若是存在应该屡次执行的代码块,则可使用setInterval()来执行该代码,setInterval()接受一个函数参数,它将以给定的毫秒延迟做为第二个参数运行无限次,就像setTimeout()同样,能够在延迟以外添加其余参数,并将这些参数传递给函数调用。也像setTimeout()同样,因为可能保留在事件循环上的操做,所以没法保证延迟,所以应将其视为近似延迟,见下面的例子:

function intervalFunc() {
  console.log('Cant stop me now!');
}

setInterval(intervalFunc, 1500);

在上面的例子中,intervalFunc()大约每1500毫秒或1.5秒执行一次,直到它被中止为止(见下文)。

setTimeout()同样,setInterval()也返回一个Timeout对象,该对象可用于引用和修改已设置的间隔。

清除将来

若是须要取消TimeoutImmediate对象,能够作些什么?setTimeout()setImmediate()setInterval()返回一个可用于引用设置TimeoutImmediate对象的计时器对象,经过将所述对象传递到相应的clear函数,将彻底中止该对象的执行。相应的函数是clearTimeout()clearImmediate()clearInterval(),请参阅下面的示例,了解每一个示例:

const timeoutObj = setTimeout(() => {
  console.log('timeout beyond time');
}, 1500);

const immediateObj = setImmediate(() => {
  console.log('immediately executing immediate');
});

const intervalObj = setInterval(() => {
  console.log('interviewing the interval');
}, 500);

clearTimeout(timeoutObj);
clearImmediate(immediateObj);
clearInterval(intervalObj);

留下超时

请记住,setTimeoutsetInterval返回Timeout对象,Timeout对象提供了两个函数,旨在使用unref()ref()来加强Timeout行为。若是使用set函数调度Timeout对象,则能够在该对象上调用unref(),这将稍微改变行为,若是它是要执行的最后一个代码,则不会调用Timeout对象,Timeout对象不会使进程保持活动状态,等待执行。

以相似的方式,调用了unref()Timeout对象能够经过在同一个Timeout对象上调用ref()来删除该行为,而后确保其执行。但请注意,出于性能缘由,这并不能彻底恢复初始行为,请参阅如下两个示例:

const timerObj = setTimeout(() => {
  console.log('will i run?');
});

// if left alone, this statement will keep the above
// timeout from running, since the timeout will be the only
// thing keeping the program from exiting
timerObj.unref();

// we can bring it back to life by calling ref() inside
// an immediate
setImmediate(() => {
  timerObj.ref();
});

进一步了解事件循环

事件循环和计时器比本指南所涵盖的要多得多,要了解有关Node.js事件循环内部以及计时器在执行期间如何操做的更多信息,请查看此Node.js指南:Node.js事件循环、定时器和process.nextTick()


上一篇:不要阻塞事件循环(或工做池)

下一篇:HTTP事务的剖析

相关文章
相关标签/搜索