Creating Sequential Tasks Using Promises
Is pretty simple. The target is to have a pre-start queue and a promise train that gets extended while new tasks are added.
The following code is an example.
class CompleteReadyStateTasks {
constructor() {
if (CompleteReadyStateTasks._instance)
throw new Error("Multiple instantiation not allowed.");
this.tasks = [];
this.taskTrain = Promise.resolve();
if (document.readyState !== 'complete') {
document.addEventListener('readystatechange', event => {
if (event.target.readyState === 'complete')
this._executePendingTasks();
});
}
CompleteReadyStateTasks._instance = this;
}
static getInstance() {
if (!CompleteReadyStateTasks._instance)
new CompleteReadyStateTasks();
return CompleteReadyStateTasks._instance;
}
_executePendingTasks() {
let task;
while (task = this.tasks.shift()) {
const _task = task;
const method = () => new Promise(resolve =>
requestAnimationFrame(async () => {
await _task();
resolve();
})
);
this.taskTrain = this.taskTrain.then(method);
}
}
_executePendingTasksIfStateComplete() {
if (document.readyState === 'complete')
this._executePendingTasks();
}
prependTask(task) {
this.tasks.unshift(task);
this._executePendingTasksIfStateComplete();
}
appendTask(task) {
this.tasks.push(task);
this._executePendingTasksIfStateComplete();
}
}
CompleteReadyStateTasks.getInstance().prependTask(() =>
document.getElementsByTagName('body')[0].classList.remove('hidden'));
CompleteReadyStateTasks.getInstance().appendTask(function() {
var d = document, s = d.createElement('script');
s.src = '//konsolebox.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
});