繁体   English   中英

Node.js中的非阻塞事件循环

[英]A Non Blocking Event Loop in Nodejs

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

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

我以以下方式尝试了在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可以实例化一个新任务作为其返回,然后将该新任务用作当前任务。
  2. 根据处理,任务状态必须更改(或者,如果采用了状态为“未处理”的新待处理任务,则不能更改)。

我相信问题是setImmediate调用,它不能更改上下文状态,因为当前执行状态永远不会终止,并且会继续为事件队列中的同一任务添加新的调用。

我希望我已经对此进行了很好的解释,并希望能有一些实施准则以及我对事件队列的理解中可能存在的任何错误。

谢谢。

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

每次循环运行时,它都会调用setImmediate()来调度要运行的任务,但是直到while循环完成后,该任务才能真正运行。 因此,您陷入了僵局,将堆积大量要运行的任务(最终可能会溢出一些系统资源)。

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

setImmediate()没有阻塞。 使用setImmediate()调度的函数要到while循环完成后才能运行,但是while循环永远不会找到其条件,因此它永远不会停止,因为在while循环完成之前没有其他东西可以运行。

相反,请调用下一个任务,完成后,再检查ctx.state 由于您没有显示或描述此方法的使用方式或您实际上要完成的工作,因此我不确定建议的最佳实现方式。 如果您需要更多帮助,则需要向我们展示很多有关您要完成的工作以及如何使用此类的信息。

我的猜测是,您可以使用promise来完成您要尝试做的事情,而不必自己编写太多基础结构代码,因为promise是用于异步任务排序的非常好的工具。


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


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM