Keep the queue moving
queue.add(function(){
sendMessage()
.then(recordSuccess)
.catch(recordFailure)
.finally(()=>this.next());
});Composition guide
The task knows whether work finished, failed, paused, or lost its connection. Let that task decide when the queue advances.
Async work
finally.When later work should proceed whether the operation succeeds or fails, place this.next() in the same cleanup boundary you already trust.
queue.add(function(){
sendMessage()
.then(recordSuccess)
.catch(recordFailure)
.finally(()=>this.next());
});queue.add(function(){
writeFile(data,error=>{
if(error) report(error);
this.next();
});
});this.next().Arrow callbacks inside the task are fine because they preserve the task's queue-bound this.
Stop gates
Set stop=true before producers add work. When the dependency is ready, clear the flag and call next() once.
const outbound=new Queue;
outbound.stop=true;
outbound.add(sendGreeting,sendPresence,requestHistory);
socket.addEventListener('open',()=>{
outbound.stop=false;
outbound.next();
});
socket.addEventListener('close',()=>{
outbound.stop=true;
});stop blocks next() without changing contents. Use it for recoverable conditions.
clear() removes everything except the currently executing task. Use it when queued intent is no longer valid.
Recovery
A synchronous task error is rethrown after running resets to false. Later tasks remain pending so the caller can clear, retry, or continue.
queue.autoRun=false;
queue.add(riskyTask,nextTask);
try{
queue.next();
}catch(error){
report(error);
// choose one policy:
queue.next(); // continue
// queue.clear(); // cancel
}The queue cannot catch them from the original next() call. Handle the promise inside the task and release deliberately.
See stop, resume, clear, and asynchronous release happen in a live queue.
Run examples