Thanks to @bergi for the answer. FWIW. Here's some code that outputs: -
Kept1234OKAfter Keptinterloperafter 2nd
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var keep;
var myPromise = new Promise(res => {keep = res;})
var demo = document.getElementById("demo");
for (var x=1; x<5; x++){
setTimeout(function(){
var myId = x;
return function()
{
myPromise.then(()=>{
demo.innerHTML += myId;
if (myId == 2) {
setTimeout(function(){demo.innerHTML += "after 2nd"},0);
myPromise.then(()=>{demo.innerHTML += "OK"})
}
});
}
}(),x*500);
}
wait(3000).then(()=>{
keep();
demo.innerHTML += "Kept";
setTimeout(function(){demo.innerHTML += "After Kept";
myPromise.then(()=>{demo.innerHTML += "interloper"}) },0)
});
function wait(time) {
return new Promise(resolve =>
{
setTimeout(resolve, time)
});
}
</script>
</body>
</html>
No where in the "duplicate" is the relevant information "So when your "event" happens while the queue is still being worked on, yes the callback does get queued up. ". This is a unique question.
NB: This question asks specifically about a JS event that fires while the .THENable chain is unwinding. For example, if there were 4 events partially completed and waiting on a promise that was just resolved and the first 2 had completed execution but Mr New Event tries THEN and continues immediately. IIUYC you say this can't happen as ALL pending-promise events complete as an atomic unit before a click or setTimeout can get in? But how did they get in when the Promise was still unresolved?
If I have several different events with .THENs waiting on a promise is the release order guaranteed to be FIFO?
For the sake of argument I'll assume the answer is "yes" but the more complicated question is what happens to a new event that now tries to THEN on an already resolved Promise? Does it immediately execute thus jumping the residual queue of pending resolution waiters?
I'm worried that we must logically single-thread access to promises for things like postMessage if we need to process messages in order :-(
For example (some justification explanation code below) if I want to post messages to my service worker then I will have to manage my own array-queue, push my message on and then "if myQueueLen == 1 setTimeout(postQueueProcessor,0)" and the queue processor event will call/fire itself till empty.
This would render promises as pretty bloody awful so I must be getting it wrong. Please advise.
var fireTravelEvent =
function(msg,callback)
{
try {
currActive.postMessage(msg);
console.log("Msg Sent to SW");
if (callback) callback();
} catch (e) {
if (e.name == "InvalidStateError" || e.name == "TypeError") {
navigator.serviceWorker.ready
.then(reg => {
currActive = reg.active;
fireTravelEvent(msg, callback)})
} else {
throw e;
}
}
}
As long as Javascript Promises support FIFO resolution the above will work but other cases will potentially have new THENers coming in with new events before ALL pending THENers have been satisfied?