在 Node.js 中休眠

Isaac Tony 2023年10月12日
  1. 使用 setTimeout() 方法来安排 Node.js 中代码的执行
  2. 使用 setInterval() 方法来安排 Node.js 中代码的执行
  3. 在 Node.js 中使用 await() 关键字暂停执行代码
在 Node.js 中休眠

在 Node.js(或一般编程)中,有些场景我们需要定期执行某些代码或脚本。Node.js 为我们提供了两个内置函数,我们可以使用它们来安排 Node.js 和 JavaScript 中函数的执行。

这些方法如下。

  1. setTimeout()
  2. setInterval()

使用 setTimeout() 方法来安排 Node.js 中代码的执行

setTimeout() 方法是一种异步方法,它允许我们在给定的时间间隔后执行一次函数。setTimeout() 函数接受许多参数,其中两个是强制性的,其余的则是可选的。

  1. 设置的时间间隔后要执行的功能
  2. 定时器在执行指定函数之前等待的毫秒数
  3. 将在设定时间后运行的某些代码超过了要执行的函数中指定的任何其他参数。

该函数返回一个称为 timeout ID 的整数,它可以引用由 setTimeout() 函数创建的对象。

这是一个使用 setTimeout() 函数以指定为毫秒的不同时间间隔执行函数的简单示例。

setTimeout(() => {console.log('This is the first function')}, 2000);
setTimeout(() => {console.log('This is the second function')}, 4000);
setTimeout(() => {console.log('This is the final function')}, 5000);

样本输出:

This is the first function
This is the second function
This is the final function

在上面的例子中,在执行第一个和第二个函数之前有 2 秒的等待时间,在执行最后一个函数之前有 1 秒的等待时间。

现在,由于 setTimeout() 是一个异步函数,我们可以改为执行最终函数。同时,第二个函数在后台等待,第一个函数最后执行,每个函数之间的等待时间为 2 秒。

setTimeout(() => {console.log('This is the first function')}, 6000);
setTimeout(() => {console.log('This is the second function')}, 4000);
setTimeout(() => {console.log('This is the final function')}, 2000);

样本输出:

This is the final function
This is the second function
This is the first function

setTimeout() 与回调函数一起使用时非常有用,可以设置回调函数在一段时间后执行。这是一个设置为在 4 秒后执行的简单回调函数。

const displayFunction =
    () => {
      console.log('Code to be executed by the display function!');
      // some more code
    }

// function may contain more parameters
setTimeout(displayFunction, 4000);

样本输出:

Code to be executed by the display function!

使用箭头函数重写代码的更精确和更可取的方法如下所示。

setTimeout(() => {console.log('Code to be executed by the function!')}, 4000)

样本输出:

Code to be executed by the function!

使用 setInterval() 方法来安排 Node.js 中代码的执行

timers 模块还为我们提供了 setInterval() 方法,其功能类似于 setTimeout() 方法。然而,与 setTimeout() 方法不同,setInterval() 方法允许我们以给定的时间间隔重复执行脚本,直到它被显式停止。

setInterval() 方法接受两个强制参数:要执行的函数和执行时间间隔。我们还可以为函数添加额外的可选参数。

该方法返回一个称为计时器 ID 的对象,可用于取消计时器。这是一个实现 setInterval() 方法的简单示例。

setInterval(() => {
  console.log('Function repeatedly executed after every 2 seconds!');
}, 2000)

样本输出:

Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
^C

此函数将重复执行,除非通过按 CTRL+C 使用键盘中断中断。在执行给定次数后停止 setInterval() 方法的更常规方法是使用 clearInterval() 函数。

我们可以通过将 setInterval() 方法返回的 ID 作为参数传递给 clearInterval() 来做到这一点,如下所示。

const id = setInterval(() => {
  console.log('Function repeatedly executed after every 2 seconds!');
}, 2000)

clearInterval(id);

我们还可以使用 setTimeout() 方法和 clearInterval() 方法在给定秒数后停止 setInterval() 方法。

这是一个简单的例子。

const id = setInterval(() => {
  console.log('Function repeatedly executed after every 2 seconds!');
}, 2000)

setTimeout(
    () => {
      clearInterval(id),
      console.log('Function stopped after 10 seconds!')
    },
    10000)

样本输出:

Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function repeatedly executed after every 2 seconds!
Function stopped after 10 seconds!

在 Node.js 中使用 await() 关键字暂停执行代码

与其他编程语言(如 C)提供 sleep 函数(允许我们在等待另一个线程执行时让给定线程休眠)不同,JavaScript 没有此函数。

然而,使用基于异步承诺的函数,我们可以使用关键字 await() 暂停一段代码的执行,直到该承诺首先得到满足。

我们将这个函数命名为 sleep();但是,这并不能阻止你将其命名为你认为合适的任何其他名称。

async 函数下,我们使用关键字 await() 暂停第二个 console.log() 函数,直到 promise 被解决;这平均需要 4 秒。Promise 返回的值被视为 await() 表达式的返回值。

async function my_asyncFunction() {
  console.log('Some Code we want to be executed');
  await sleep(4000);
  console.log('Some other code we want to be executed after some seconds');
}

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

my_asyncFunction();

样本输出:

Some Code we want to be executed
Some other code we want to be executed after some seconds

到目前为止,我们还不能在常规 Javascript 代码中的 async 函数之外使用 await() 表达式。任何使用该语法的尝试都会返回语法错误。

async function my_asyncFunction() {
  console.log('Some Code we want to be executed');

  console.log('Some other code we want to be executed after some seconds');
}

await sleep(4000);
function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

my_asyncFunction();

样本输出:

E:\Tonyloi>await.js:7
await sleep(4000);
^^^^^

SyntaxError: await is only valid in async functions and the top level bodies of modules
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1031:15)
    at Module._compile (node:internal/modules/cjs/loader:1065:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47

但是,我们可以在 JavaScript 模块语法中的 async 函数之外使用 await 表达式。

作者: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn