I was trying to implement an event loop. The purpose of the loop is simple:
- If, the queue is not empty, let task be the oldest entry in the queue.
- Process task
- If, task generates a return value, cache it.
- Check the queue for task.
- If, the queue is not empty, adopt the next task as the current task context.
- Pass the cached return value to the new task.
I tried an implementation in Nodejs in the following manner:
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'
});
}
}
The differences between this implementation and that of an event loop are as follows:
- Rather than maintaining an array of task, the successCallback can instantiate a new task as its return which, is then adopted as the current task.
- Based on the processing, the task state must change (or not, if, a new pending task is adopted which, has its state as 'unprocessed').
I believe the problem is the setImmediate invocation which, cannot change the context state because, the current execution state never terminates and keeps adding a new call for the same task in the event queue.
I hope I have explained it well and would appreciate some guidelines for implementation and, any errors that I may have in my understanding of the event queue.
Thanks.