我试图实现一个事件循环。循环的目的很简单:
- 如果队列不为空,则令任务为队列中最旧的条目。
- 处理任务
- 如果,任务产生一个返回值,缓存它。
- 检查队列中的任务。
- 如果队列不为空,则采用下一个任务作为当前任务上下文。
- 将缓存的返回值传递给新任务。
我以以下方式在 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'
});
}
}
此实现与事件循环的实现之间的区别如下:
- successCallback 可以实例化一个新任务作为其返回,而不是维护一个任务数组,然后将其作为当前任务采用。
- 基于处理,任务状态必须改变(或者不改变,如果采用新的挂起任务,其状态为“未处理”)。
我认为问题在于 setImmediate 调用,它无法更改上下文状态,因为当前执行状态永远不会终止,并不断在事件队列中为同一任务添加新调用。
我希望我已经很好地解释了它,并且会感谢一些实施指南,以及我在理解事件队列时可能遇到的任何错误。
谢谢。