资讯专栏INFORMATION COLUMN

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

econi / 2621人阅读

摘要:中的定时器中的模块包含在一段时间后执行代码的函数,定时器不需要通过导入,因为所有方法都可以在全局范围内模拟浏览器,要完全了解何时执行定时器功能,最好先阅读事件循环。

Node.js中的定时器

Node.js中的Timers模块包含在一段时间后执行代码的函数,定时器不需要通过require()导入,因为所有方法都可以在全局范围内模拟浏览器JavaScript API,要完全了解何时执行定时器功能,最好先阅读Node.js事件循环。

用Node.js控制时间连续性

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

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

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

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

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

setTimeout(myFunc, 1500, "funky");

由于调用了setTimeout(),上面的函数myFunc()将尽可能接近1500毫秒(或1.5秒)执行。

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

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

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

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

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事务的剖析

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100228.html

相关文章

  • Node.js 指南(目录)

    Node.js 指南 Node.js®是基于Chrome的V8 JavaScript引擎构建的JavaScript运行时。 常规 关于Node.js 入门指南 轻松分析Node.js应用程序 Docker化Node.js Web应用程序 迁移到安全的Buffer构造函数 Node.js核心概念 阻塞与非阻塞概述 Node.js事件循环、定时器和process.nextTick() 不要阻塞事...

    未东兴 评论0 收藏0
  • Node.js 指南Node.js事件循环、时器和process.nextTick())

    摘要:检索新的事件执行与相关的回调几乎所有,除了由定时器调度的一些和将在适当的时候在这里阻塞。在事件循环的每次运行之间,检查它是否在等待任何异步或定时器,如果没有,则彻底关闭。 Node.js事件循环、定时器和process.nextTick() 什么是事件循环? 事件循环允许Node.js执行非阻塞I/O操作 — 尽管JavaScript是单线程的 — 通过尽可能将操作卸载到系统内核。 ...

    pingink 评论0 收藏0
  • Node.js 指南(阻塞与非阻塞概述)

    摘要:标准库中的所有方法都提供非阻塞的异步版本,并接受回调函数,某些方法还具有对应的阻塞方法,其名称以结尾。比较代码阻塞方法同步执行,非阻塞方法异步执行。 阻塞与非阻塞概述 此概述介绍了Node.js中阻塞与非阻塞调用之间的区别,此概述将引用事件循环和libuv,但不需要事先了解这些主题,假设读者对JavaScript语言和Node.js回调模式有基本的了解。 I/O主要指与libuv支持的...

    zebrayoung 评论0 收藏0
  • 【译】Node.js 前端开发指南

    摘要:定时器在和浏览器中的表现形式是相同的。关于定时器的一个重要的事情是,我们提供的延迟不代表在这个时间之后回调就会被执行。它的真正含义是,一旦主线程完成所有操作包括微任务并且没有其它具有更高优先级的定时器,将在此时间之后执行回调。 众成翻译 原文链接 关于作者 2018年6月21日出版​ 本指南面向了解Javascript但尚未十分熟悉Node.js的前端开发人员。我这里不专注于语言本身...

    CntChen 评论0 收藏0
  • Node.js API参考文档(目录)

    摘要:参考文档是基于的引擎构建的运行时。关于文档用法和示例断言测试稳定性稳定模块提供了一组简单的断言测试,可用于测试不变量。存在和模式,但建议仅使用模式。类在全局作用域内,因此不太可能需要使用。以下所有示例均可供下载,可用作扩展库的起点。 Node.js v11.5.0 API参考文档 Node.js®是基于Chrome的V8 JavaScript引擎构建的JavaScript运行时。 关...

    stormzhang 评论0 收藏0

发表评论

0条评论

econi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<