Nodejs 中的非阻塞事件循环

A Non Blocking Event Loop in Nodejs

我试图实现一个事件循环。循环的目的很简单:

  1. 如果队列不为空,让任务成为队列中最早的条目。
  2. 处理任务
  3. 如果任务生成一个 return 值,缓存它。
  4. 检查任务队列。
  5. 如果,队列不为空,则采用下一个任务作为当前任务上下文。
  6. 将缓存的 return 值传递给新任务。

我尝试通过以下方式在 Nodejs 中实现:

function task(){
this.task = Array.prototype.shift.call(arguments);
this.state = 'unprocessed';
this.successCallback = null;
this.failureCallback = null;
}
task.prototype.afterThat = function(){
if(arguments.length > 1){
this.successCallback = Array.prototype.shift.call(arguments);
this.failureCallback = Array.prototype.shift.call(arguments);
}
}
task.prototype._loop = function(){
let ctx = this;
while(ctx.state === 'unprocessed'){ // Source of problem
    setImmediate(this.task, function(){
    // change ctx.state if needed
   }, function(){
   // change ctx.state to 'processed'
   });
 }
}

这种实现方式与事件循环方式的区别如下:

  1. successCallback 可以实例化一个新任务作为其 return 而不是维护一个任务数组,然后将其作为当前任务采用。
  2. 基于处理,任务状态必须改变(或者不改变,如果采用新的挂起任务,其状态为'unprocessed')。

我认为问题出在 setImmediate 调用上,它无法更改上下文状态,因为当前执行状态永远不会终止,并且不断为事件队列中的同一任务添加新的调用。

我希望我已经很好地解释了它,并感谢一些实施指南,以及我在理解事件队列时可能遇到的任何错误。

谢谢。

你的 while 循环是一个无限循环。 JS 是单线程的,因此在 while 循环完成之前,其他任何东西都不能 运行。因为没有别的可以运行,ctx.state永远不会改变。因为 ctx.state 永远不会改变,所以你的 while 循环永远 运行。

每次循环 运行 调用 setImmediate() 将任务安排到 运行,但该任务实际上 运行 直到 [=10] =] 循环结束。因此你陷入了僵局,你将把大量任务堆积到 运行(最终可能会溢出一些系统资源)。

您需要在完成 运行 任务后检查 ctx.state(可能在成功和失败回调中),而不是在这样的循环中。

setImmediate() 没有阻塞。在 while 循环完成之前,您使用 setImmediate() 安排的功能不会 运行,但是 while 循环永远不会找到它的条件,所以它永远不会停止,因为没有其他东西可以 运行 直到 while 循环完成。

相反,调用下一个任务,当它完成时,然后检查 ctx.state。由于您没有展示或描述它的使用方式或您真正想要完成的事情,因此我不确定建议的最佳实施方式。如果您在这方面需要更多帮助,那么您需要向我们展示更多关于您想要完成的事情以及您希望如何使用它 class.

我的猜测是,您可以使用 promises 来完成您想要做的事情,而无需自己编写很多基础结构代码,因为 promises 是对异步任务进行排序的非常好的工具。


仅供参考,您的代码有几处错误,例如缺少右大括号和括号。您发布的内容甚至无法正确解析,更不用说 运行。并且,发帖时请适当缩进代码