NodeJs-Timers

class Timers

Node.js 的 Timers 模块提供了与时间相关的函数,主要用于设置和清除定时器。该模块的功能包括让代码在指定时间后执行一次、定期执行,或将代码推迟到事件循环的下一次迭代中执行。

尽管 Timers 模块是一个内置模块,但你不需要显式地 require 它,因为这些函数是全局可用的。以下是 Timers 模块的详细说明,涵盖了它的所有方法和属性。


1. setTimeout()

setTimeout() 用于在指定的延迟时间后执行一次代码。

setTimeout(callback, delay, ...args);
  • callback: {Function} 在延迟时间到达后要执行的函数。
  • delay: {number} 延迟的时间(以毫秒为单位)。
  • ...args: 可选参数,传递给 callback 函数。
示例:
setTimeout(() => {
  console.log('Hello, world!');
}, 1000);  // 1秒后打印 'Hello, world!'

2. clearTimeout()

clearTimeout() 用于取消通过 setTimeout() 设置的定时器。

clearTimeout(timeoutObject);
  • timeoutObject: {Timeout} 由 setTimeout() 返回的定时器对象。
示例:
const timer = setTimeout(() => {
  console.log('This will not run');
}, 5000);

clearTimeout(timer);  // 取消定时器,回调函数不会执行

3. setInterval()

setInterval() 用于每隔指定的时间重复执行代码。

setInterval(callback, delay, ...args);
  • callback: {Function} 每次间隔时间到达后要执行的函数。
  • delay: {number} 时间间隔(以毫秒为单位)。
  • ...args: 可选参数,传递给 callback 函数。
示例:
setInterval(() => {
  console.log('This message prints every second');
}, 1000);  // 每秒打印一次消息

4. clearInterval()

clearInterval() 用于取消通过 setInterval() 设置的定时器。

clearInterval(intervalObject);
  • intervalObject: {Timeout} 由 setInterval() 返回的定时器对象。
示例:
const interval = setInterval(() => {
  console.log('This will stop after 3 seconds');
}, 1000);

setTimeout(() => {
  clearInterval(interval);  // 3秒后停止定时器
}, 3000);

5. setImmediate()

setImmediate() 用于将代码推迟到事件循环的下一次迭代中执行。这与 setTimeout() 不同,后者至少等待一个指定的延迟时间,而 setImmediate() 则是在当前事件循环完成后尽快执行。

setImmediate(callback, ...args);
  • callback: {Function} 在事件循环的下一次迭代中执行的函数。
  • ...args: 可选参数,传递给 callback 函数。
示例:
console.log('Before immediate');

setImmediate(() => {
  console.log('Executed in the next event loop iteration');
});

console.log('After immediate');

输出顺序:

Before immediate
After immediate
Executed in the next event loop iteration

6. clearImmediate()

clearImmediate() 用于取消通过 setImmediate() 设置的操作。

clearImmediate(immediateObject);
  • immediateObject: {Immediate} 由 setImmediate() 返回的对象。
示例:
const immediate = setImmediate(() => {
  console.log('This will not run');
});

clearImmediate(immediate);  // 取消 `setImmediate` 回调

7. process.nextTick()

process.nextTick() 用于在当前操作结束后立即执行回调函数,而不是推迟到下一个事件循环。这在优先级上比 setImmediate() 更高。

process.nextTick(callback, ...args);
  • callback: {Function} 当前操作结束后执行的回调函数。
  • ...args: 可选参数,传递给 callback 函数。
示例:
console.log('Before nextTick');

process.nextTick(() => {
  console.log('Executed after the current operation');
});

console.log('After nextTick');

输出顺序:

Before nextTick
After nextTick
Executed after the current operation

8. async/await 配合使用

setTimeout()setImmediate()process.nextTick() 都可以通过 Promiseasync/await 来封装,以便在异步操作中使用。

示例:
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function asyncOperation() {
  console.log('Start operation');
  await delay(2000);  // 等待2秒
  console.log('End operation');
}

asyncOperation();

9. Timer 对象

setTimeout()setInterval()setImmediate() 返回的对象上,都有相应的属性和方法可以进一步操作定时器。这些方法允许在定时器执行之前将其取消,或者获取与其相关的状态。


10. Timeout vs Immediate vs NextTick

  • setTimeout(callback, delay):至少等待 delay 毫秒后执行回调函数。
  • setImmediate(callback):当前事件循环完成后尽快执行回调函数。
  • process.nextTick(callback):在当前操作完成后立即执行回调,优先级最高。
优先级顺序:

process.nextTick() > setImmediate() > setTimeout()


11. Timers Promises API

从 Node.js v15.0.0 开始,timers/promises 模块引入了 Promise 风格的 setTimeout()setImmediate()

示例:
import { setTimeout } from 'timers/promises';

async function run() {
  console.log('Waiting for 1 second...');
  await setTimeout(1000);
  console.log('Done!');
}

run();

你还可以传递一个 AbortSignal 来中止定时操作:

import { setTimeout } from 'timers/promises';
import { AbortController } from 'node:abort-controller';

const ac = new AbortController();

setTimeout(1000, null, { signal: ac.signal })
  .then(() => console.log('Done!'))
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('Operation was aborted');
    } else {
      throw err;
    }
  });

// 中止定时器
ac.abort();

总结

Timers 模块是 Node.js 中用于处理异步操作的核心模块之一。通过这些定时器函数,你可以实现延时执行、周期性执行、事件循环中的任务调度等功能。了解这些函数的优先级和适用场景是编写高效异步代码的关键。

评论区
评论列表
menu