我试图实现一个事件循环。循环的目的很简单:
我尝试以下列方式在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'
});
}
}
此实现与事件循环之间的差异如下:
我认为问题是setImmediate调用,它无法更改上下文状态,因为当前执行状态永远不会终止并继续为事件队列中的同一任务添加新调用。
我希望我已经很好地解释了它,并希望了解一些实施指南,以及我在理解事件队列时可能遇到的任何错误。
感谢。
答案 0 :(得分:2)
你的while
循环是一个无限循环。 JS是单线程的,因此在while
循环完成之前,其他任何东西都无法运行。因为没有别的东西可以运行,ctx.state
永远不会改变。因为ctx.state
永远不会改变,所以while
循环会永远运行。
每次循环运行时,它会调用setImmediate()
来调度要运行的任务,但该任务实际上无法运行,直到while
循环结束。因此,您将陷入僵局,并且您将堆积大量要运行的任务(最终可能会溢出某些系统资源)。
在完成任务运行后(可能在成功和失败回调中),您需要检查ctx.state
,而不是像这样的循环。
setImmediate()
没有阻止。您使用setImmediate()
计划的功能在while
循环完成之前不会运行,但while
循环永远不会找到它的条件,因此它永远不会停止,因为在{{1循环完成。
相反,请调用下一个任务,完成后再检查while
。由于您没有显示或描述如何使用或您真正想要实现的目标,因此我不确定建议的最佳实施方式。如果您需要更多帮助,那么您需要向我们展示更多关于您尝试完成的内容以及您希望如何使用此课程的内容。
我的猜测是你可以使用promises来完成你想要做的事情,而不必自己编写很多基础设施代码,因为promises是非常好的异步任务排序工具。
仅供参考,您的代码存在一些问题,例如缺少关闭括号和parens。您发布的内容甚至无法正确解析,更不用说运行了。并且,请在发布时正确缩进代码。