本文介绍: 定时器timers 模块对外暴露一个全局的API用于调度在某个时段调用函数因为定时器函数全局变量,所以不需要加载timers 模块使用它。Node.s定时器函敬实现了与 Web 浏览器提供的定时器 API 类似的 AP,但是它们使用了不同的内部实现机制,Nodeis定时器函数是基于 Node.s 事件循环构建的。

定时器timers 模块对外暴露一个全局的API用于调度在某个时段调用的函数因为定时器函数是全局变量,所以不需要加载timers 模块来使用它。Node.s定时器函敬实现了与 Web 浏览器提供的定时器 API 类似的 AP,但是它们使用了不同的内部实现机制,Nodeis定时器函数是基于 Node.s 事件循环构建的。

设置定时

Node.js 中的定时器在一段时间后会调用给定的函数。何时调用定时器函数取决于用来创建定时器的方法及Node.is 事件循环正在执行的其他工作

1, 一次性定时器

基本用法:

setTimeout(callbackdelay[,...argsl)

这个方法用于延迟一个函数的执行时间,在到达指定时间点执行该函数,并且只执行一次。其中参数 callback 用于指定要调用的回调函数,delay 设置调用回调函数之前等待毫秒数,args 设置调用回调函数时传入的可选参数。它返回 Timeout 对象的ID,该D 可以传递clearTimeOut0)以取消该定时器。例如,下面的代码将在 1秒后输出提示信息,之后定时器就不再起作用

setTimeout(function()
	console.log('我是一个一次性的定时器');
},1000);

定时器可能不会精确地在指定的时刻调用回调函数。Node.js 不保证回调触发的确切时间,也不保证它们的顺序回调函数会尽可能接近指定时间,并在该时间点被调用。

2.周期性定时器

基本用法:

setInterval(callbackdelay[,...argsl)

这个方法用于指定时间间隔周期性地执行回调函数,其参数返回值同上述 setTimeout0)方法参数返回值

例如,下面的代码将在 1 秒之后输出提示信息,之后定时器每隔 1 秒就重复输出提示信息,除非使用clearlnterval( )方法取消该定时器,或者终止程序

setInterval (function(){
	console.log('我是一个周期性的定时器');
},1000);

3.即时定时器

基本用法:

setImmediate(callback[...args])

这个方法用于在 I/O 事件回调之后立即执行回调函数,其比上述 setTimeout0方法少了一个 delay参数返回的是Immediate 对象

这是一个即时定时器,该方法并不会立即执行回调函数,而是在事件轮询之后执行函数,为了防止轮询阻塞,在每轮循环中仅执行链表中的一个回调函数。当程序多次调用 setlmmediate0)方法时,由该参数指定的回调函数将按照创建它们的顺序排队等待执行。每次事件循环迭代都会处理整个回调队列。如果即时定时器通过正在执行的回调加入队列,则要等到下一次事件循环迭代时才会被触发

取消定时器

上述 setTimeout( )、setlnterval( )和 setlmmediate( )方法各自返回表示设置的定时器的对象,这些对象可以用来取消定时器并防止该定时器触发,分别用 cearTimeout( )、cearinterval( )和clearlmmediate( )方法取消相应定时器。

例如,以下代码使用 setinterval( )方法设置周期性定时器后,使用clearinterval( )方法取消定时期

var testInterval=setInterval(testFunc,2000);
clearInterval(testInterval);

Timeout 和 Immediate 类

Node.js 内置两个与定时器相关的类:Timeout 和 Immediate。可以使用 setTimeout() 或 setInterval() 方法创建 Timeout 对象,并使用 clearTimeout() 或 clearInterval() 方法取消定时器。默认情况下,当设置了定时器后,Node.js 事件循环将继续执行。

Timeout 对象提供了 timeout.ref() 和 timeout.unref() 方法,用于控制定时器的默认行为ref() 方法将定时器添加事件循环中,使其保持活动状态,而 unref() 方法将定时器从事件循环中移除,使其不再影响事件循环的执行。

Immediate 对象可以使用 setImmediate() 方法创建,并使用 clearImmediate() 方法取消即时定时器。默认情况下,当设置了即时定时器后,Node.js 事件循环将继续执行。

Immediate 对象提供了 immediate.ref() 和 immediate.unref() 方法,用于控制即时定时器的默认行为ref() 方法将即时定时器添加到事件循环中,使其保持活动状态,而 unref() 方法将即时定时器从事件循环中移除,使其不再影响事件循环的执行。

需要注意的是,在 setTimeout() 或 setInterval() 方法中,this 关键字在 JavaScript 中指向 window 对象,而在 Node.js指向 Timeout 对象。

setImmediate() 方法和 setTimeout() 方法

与 setTimeout() 方法相比,setImmediate() 方法的主要优点是,无论在一个 I/O 周期内有多少个定时器,setImmediate() 方法都会在当前事件循环迭代末尾执行。

方法 setImmediate() setTimeout()
执行时机 在事件循环的下一个迭代中立即执行 在指定的延迟时间后执行
执行顺序 当前事件循环迭代的末尾执行 在当前事件循环迭代的末尾执行
延迟时间 延迟,立即执行 可以设置延迟时间
取消定时器 使用 clearImmediate() 方法 使用 clearTimeout() 方法
默认行为 在活动状态下,不会阻塞事件循环 在活动状态下,不会阻塞事件循环
控制默认行为 使用 immediate.ref() 和 immediate.unref() 方法 使用 timeout.ref() 和 timeout.unref() 方法
this 关键字 指向 Immediate 对象 指向 Timeout 对象

一个IO周期(即主模块)内执行两个定时器函数(timeout_vs immediate1.js)

setTimeout(() => {
  console.log('一次性');
}, 0);

setImmediate(() => {
  console.log('即时性');
});

在这个例子中,setTimeout() 设置了一个延迟时间为 0 的定时器,而 setImmediate() 设置了一个即时定时器。

在一个 I/O 周期内调用这两个方法时,它们的执行顺序是不确定的,因为它们都是在当前事件循环迭代的末尾执行。具体执行顺序可能受到事件循环的状态和其他异步操作影响

执行结果

PS D:WuWorkSpacecodeNodejsProjectnodejs实战学习【第2章  Node.js基础】2.5计时器> node .timeout_vs_immediate.js
即时性
一次性
PS D:WuWorkSpacecodeNodejsProjectnodejs实战学习【第2章  Node.js基础】2.5计时器> node .timeout_vs_immediate.js
一次性
即时性

但是,如果将这两个函数放入一个I/O 循环内,那么setlmmediate 总是被优先调用

同一个I/O 循环内执行两个定时器函数(timeout_vs immediate2.js)

const fs = require('fs');
fs.readFile(__filename, () => {
  setTimeout(() => {
    console.log('一次性');
  }, 0);
  setImmediate(() => {
    console.log('即时性');
  });
});

执行结果如下


PS D:WuWorkSpacecodeNodejsProjectnodejs实战学习【第2章  Node.js基础】2.5计时器> node '.timeout_vs immediate2.js'
即时性
一次性
PS D:WuWorkSpacecodeNodejsProjectnodejs实战学习【第2章  Node.js基础】2.5计时器> node '.timeout_vs immediate2.js'
即时性
一次性
PS D:WuWorkSpacecodeNodejsProjectnodejs实战学习【第2章  Node.js基础】2.5计时器> node '.timeout_vs immediate2.js'
即时性
一次性

process.nextTick()setImmediate()

process.nextTick()setImmediate() 都是用于在 Node.js 中执行异步操作的方法,但它们之间有一些重要的区别

下面是 process.nextTick()setImmediate() 的对比:

方法 process.nextTick() setImmediate()
执行时机 在当前操作完成后,下一个事件循环迭代之前执行 在当前事件循环的末尾执行
执行顺序 在当前事件循环迭代中的最后执行 在当前事件循环迭代的末尾执行
优先级 优先级,比其他异步操作(包括定时器)更早执行 优先级,比其他异步操作(包括定时器)稍后执行
嵌套调用 允许嵌套调用,可以无限递归 不允许嵌套调用,避免无限递归
控制默认行为 无法控制默认行为 使用 immediate.ref() 和 immediate.unref() 控制默认行为
this 关键字 指向当前模块exports 对象 指向 Immediate 对象

总的来说,process.nextTick() 方法具有更高的优先级,它会在当前操作完成后立即执行,而不需要等待下一个事件循环迭代。这使得它在需要优先执行的情况下非常有用,例如处理错误回调或需要立即更新状态的情况下。

相比之下,setImmediate() 方法在当前事件循环迭代的末尾执行,它的优先级较低。它适用于需要在当前事件循环迭代的末尾执行回调函数的情况,避免阻塞其他异步操作

需要注意的是,process.nextTick() 方法允许嵌套调用,这意味着可以在回调函数中再次调用 process.nextTick(),从而形成无限递归。而 setImmediate() 方法不允许嵌套调用,避免了无限递归的问题

原文地址:https://blog.csdn.net/No_Name_Cao_Ni_Mei/article/details/134337299

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_28198.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注