在 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