當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Node.js process.nextTick(callback[, ...args])用法及代碼示例

process.nextTick(callback[, ...args])

曆史
版本變化
v18.0.0

將無效回調傳遞給 callback 參數現在會拋出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK

v1.8.1

現在支持 callback 之後的附加參數。

v0.1.26

添加於:v0.1.26


參數

process.nextTick()callback 添加到“下一個滴答隊列”。在 JavaScript 堆棧上的當前操作運行完成後且在允許事件循環繼續之前,此隊列已完全排空。如果要遞歸調用 process.nextTick() ,則可以創建無限循環。有關更多背景信息,請參閱Event Loop 指南。

import { nextTick } from 'node:process';

console.log('start');
nextTick(() => {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callbackconst { nextTick } = require('node:process');

console.log('start');
nextTick(() => {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback

這在開發 API 時很重要,以便讓用戶有機會在構造對象之後但發生任何 I/O 之前分配事件處理程序:

import { nextTick } from 'node:process';

function MyThing(options) {
  this.setupOptions(options);

  nextTick(() => {
    this.startDoingStuff();
  });
}

const thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.const { nextTick } = require('node:process');

function MyThing(options) {
  this.setupOptions(options);

  nextTick(() => {
    this.startDoingStuff();
  });
}

const thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.

API 或者 100% 同步,或者 100% 異步,這一點非常重要。考慮這個例子:

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
}

此 API 很危險,因為在以下情況下:

const maybeTrue = Math.random() > 0.5;

maybeSync(maybeTrue, () => {
  foo();
});

bar();

不清楚是先調用foo() 還是bar()

以下方法要好得多:

import { nextTick } from 'node:process';

function definitelyAsync(arg, cb) {
  if (arg) {
    nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}const { nextTick } = require('node:process');

function definitelyAsync(arg, cb) {
  if (arg) {
    nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}

何時使用queueMicrotask()對比process.nextTick()#

queueMicrotask() API 是 process.nextTick() 的替代方案,它還使用相同的微任務隊列來延遲函數的執行,該微任務隊列用於執行已解決的 promise 的 then、catch 和 finally 處理程序。在 Node.js 中,每次“下一個滴答隊列”被排空時,微任務隊列都會在之後立即被排空。

import { nextTick } from 'node:process';

Promise.resolve().then(() => console.log(2));
queueMicrotask(() => console.log(3));
nextTick(() => console.log(1));
// Output:
// 1
// 2
// 3const { nextTick } = require('node:process');

Promise.resolve().then(() => console.log(2));
queueMicrotask(() => console.log(3));
nextTick(() => console.log(1));
// Output:
// 1
// 2
// 3

對於大多數用戶級用例,queueMicrotask() API 提供了一種可移植且可靠的延遲執行機製,該機製適用於多個 JavaScript 平台環境,應該優於 process.nextTick()。在簡單的場景中,queueMicrotask() 可以是 drop-in 替代 process.nextTick()

console.log('start');
queueMicrotask(() => {
  console.log('microtask callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// microtask callback

兩個 API 之間的一個 note-worthy 區別是 process.nextTick() 允許指定附加值,這些值將在調用延遲函數時作為參數傳遞。使用 queueMicrotask() 實現相同的結果需要使用閉包或綁定函數:

function deferred(a, b) {
  console.log('microtask', a + b);
}

console.log('start');
queueMicrotask(deferred.bind(undefined, 1, 2));
console.log('scheduled');
// Output:
// start
// scheduled
// microtask 3

處理下一個滴答隊列和微任務隊列中引發的錯誤的方式存在細微差別。隊列中的微任務回調中拋出的錯誤應盡可能在隊列中的回調中處理。如果不是,process.on('uncaughtException') 事件處理程序可用於捕獲和處理錯誤。

如有疑問,除非需要 process.nextTick() 的特定函數,否則請使用 queueMicrotask()

相關用法


注:本文由純淨天空篩選整理自nodejs.org大神的英文原創作品 process.nextTick(callback[, ...args])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。