В простом случае можно просто вызывать рекурсивно.
Вот вариант с явной очередью:
<html>
<head>
</head>
<body>
<script>
ModalWindow = {
layer: document.createElement("div"),
window: document.createElement("div")
}
with(ModalWindow) {
with(layer.style){
position = "fixed"
width = "100%"
height = "100%"
background = "black"
opacity = "0.5"
left = "0"
top = "0"
}
with(window.style){
position = "fixed"
top = left = "35%"
background = "white"
opacity = "1"
width = height = "30%"
border = "1px solid black"
textAlign = "center"
fontSize = "30px"
}
}
ModalWindow.createWithMessage = function(message, callback){
var window = Object.create(this)
window.message = message
return window
}
Object.defineProperty(ModalWindow, "show", {get: function(){
document.body.appendChild(this.layer)
document.body.appendChild(this.window)
this.window.innerHTML = this.message
}})
Object.defineProperty(ModalWindow, "hide", {get: function(){
document.body.removeChild(this.layer)
document.body.removeChild(this.window)
this.queue.run
}})
///////////
Queue = {}
Object.defineProperty(Queue, "create", {get: function(){
var queue = Object.create(this)
queue.queue = []
return queue
}})
Queue.append = function(object){
object.queue = this
this.queue.unshift(object)
}
Object.defineProperty(Queue, "run", {get: function(){
if(this.running) delete this.running.queue
if(!this.queue.length) return
this.running = this.queue.pop()
this.running.queue = this
this.action(this.running)
}
})
Object.defineProperty(window, "random", {get: function(){return Math.floor( Math.random() * 3000 + 3000 )}})
with( queue = Queue.create ) {
append(ModalWindow.createWithMessage("foo"))
append(ModalWindow.createWithMessage("bar"))
append(ModalWindow.createWithMessage("baz"))
}
queue.action = function(modalWindow){
setTimeout(function(){
modalWindow.show
setTimeout(function(){modalWindow.hide}, random)
}, 500)
}
////////
queue.run
</script>
</body>
</html>
Если очередь детерминирована перед началом итераций, вероятно, вместо unshft, выгодней использовать push и reverse после наполнения.
В случае, если к реализации итерируемого объекта нет доступа, можно использовать MutationObserver, и ловить напрямую события перерисовки страницы(события DOM)