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


稳定性: 3 - 传统:请改用 queueMicrotask()

  • callback <Function>
  • ...args <any> 调用 callback 时要传递的额外参数

process.nextTick() 会将 callback 添加到“下一次执行队列”。这个队列会在当前 JavaScript 栈上的操作完成后、事件循环继续之前被完全清空。如果递归调用 process.nextTick(),可能会创建一个无限循环。有关更多背景信息,请参见 事件循环 指南。

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 发生之前,有机会分配事件处理程序:

【This is important when developing APIs in order to give users the opportunity to assign event handlers after an object has been constructed but before any I/O has occurred:】

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 来说,要么完全同步,要么完全异步,这是非常重要的。考虑以下示例:

【It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example:】

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

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

此 API 是危险的,因为在以下情况下:

【This API is hazardous because in the following case:】

const maybeTrue = Math.random() > 0.5;

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

bar(); 

目前尚不清楚是先调用 foo() 还是 bar()

【It is not clear whether foo() or bar() will be called first.】

以下方法要好得多:

【The following approach is much better:】

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);
}