阻塞事件循环,我想实现一个事件循环。循环的目的很简单:A暂无在的NodeJS
- 如果队列不空,让任务在队列中的最老的项目。
- 进程任务
- 如果任务生成返回值,则将其缓存。
- 检查队列中的任务。
- 如果队列不为空,采取下一个任务作为当前任务的上下文。
- 将缓存的返回值传递给新任务。
我尝试一个实现中的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调用,它不能更改上下文状态,因为当前执行状态永远不会终止,并且不断为事件队列中的同一任务添加新的调用。
我希望我已经解释清楚了,并希望得到一些实施指南,以及我对理解事件队列的任何错误。
谢谢。
我建议更好地缩进你的代码。我相信你定义'task.prototype.afterThat'的'里面task.prototype._loop'。 –
你'while'循环是一个无限循环。 JS是单线程的,因此没有别的东西可以运行,因为你的while循环。完成运行任务后,您需要检查'ctx.state'。 'setImmediate()'不是阻塞的。它不运行,直到你'while'循环完成这是一个无限循环,所以它从来没有做过。 – jfriend00