【问题标题】:JavaScript / Node.js event loop tick idsJavaScript / Node.js 事件循环刻度 ID
【发布时间】:2021-04-16 01:45:30
【问题描述】:

我想知道是否有一些巧妙的方法可以知道函数是在当前刻度(声明函数的刻度)还是 Node.js 事件的下一个刻度(或未来的某个刻度)中调用的循环

例如:

function foo(cb){

  // we can fire callback synchronously
  cb();

  // or we can fire callback asynchronously
  process.nextTick(cb);

}

say 会像这样调用 foo:

function outer(){

   const currentTickId = process.currentTickId;

  function bar(){          //bar gets created everytime outer is called..

    if(process.currentTickId === currentTickId){
       //do something
    }
    else{

     // do something else
    }


  }

  // foo is always called in the same tick that bar was
  // declared, but bar might not be called until the next tick

  foo(bar);  


}

大多数应用程序不需要这样的东西,但我正在编写一个库,如果可能的话,拥有这个功能会很有用!注意process.currentTickId是我为这个例子编造的

【问题讨论】:

  • 我猜这是“可能的” - npmjs.com/package/tick-id
  • 请注意,通常最好的做法是始终异步触发回调,但这只是一个说明性示例
  • 仅供参考,无法知道函数调用是同步还是异步的状态在 JS 社区中被称为 Zalgo - 这种用法早于“zalgo text”至少 1 1/2 年。它被认为是一种反模式

标签: javascript node.js


【解决方案1】:

您似乎已经发现了process.nextTick

您可以使用它来安装系统以实现“process.currentTickId”,因为您问题中的代码表明您需要:

process.currentTickId = 0;

const onTick = () => {
    process.currentTickId++;
    process.nextTick(onTick);
};

process.nextTick(onTick);

【讨论】:

  • 啊你缺少的是,这是一个将被开发人员使用的库。我希望他们能够同步调用 API,但是如果他们在 nextTick 中调用 API,则会发出警告或抛出错误,所以我根本无法控制他们何时使用同步或异步代码,这不是我的代码,而是他们的。
  • 关于此代码的一点警告,当您从 onTick 内部将 onTick 推送到从下一个滴答队列触发的下一个滴答队列时,您基本上会阻塞事件循环并且它永远不会耗尽下一个滴答队列.事件循环的其他部分永远不会触发,包括超时、立即、承诺、I/O 事件等。
  • @AdamLockhart 你试过这个代码吗?怀疑这是真的 - node.js 有不同类别的异步回调/任务要处理 - 某些事情总是在 nextTick 调用之前和 nextTick 调用事件循环的每个周期之后运行。换句话说,每次事件循环处理它的任务时——它总是会在处理 nextTick 请求之前查看其他要处理的事情。
  • @Emmett 我希望node.js核心可以为我们添加一个id,这样我们就不用添加运行时监听了
  • 其实亚当是对的。我在3年前遇到过这种情况。我很惊讶为什么我的网络请求不起作用,我发现递归调用 process.nextTick 意味着“某些总是在 nextTick 调用之后运行的事情”永远不会执行(而网络 I/O 恰好是其中之一)。我通过用setTimeout(.., 0) 替换nextTick 解决了这个问题。本质上,您永远不会进入“在 nextTick 调用之后”的状态,也永远不会退出当前事件循环
【解决方案2】:

NPM 库: https://www.npmjs.com/package/event-loop-ticks

基于@Emmett 帖子改进的答案:

let _tick = 0;
const onTick = () => {
  _tick++;
  setImmediate(() => process.nextTick(onTick)).unref();
};
process.nextTick(onTick);

【讨论】:

    猜你喜欢
    • 2015-10-13
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2016-12-15
    • 2015-07-14
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    相关资源
    最近更新 更多