While working on my web app, specifically file uploads, Chrome displayed a warning after I called an alert:
Invoking \'alert()\' during microtask executio
Yes, the warning is justified: You're calling alert
within a microtask, in this case a promise completion. (See Difference between microtask and macrotask within an event loop context.)
alert
, prompt
, and confirm
are relics of an age long past, and they have a problem: They completely interrupt the normal workings of JavaScript and arguably violate its run-to-completion semantics by completely suspending execution, right in the middle of a job from the job queue (or a task from the event loop; JavaScript and the HTML5 spec differ on terminology) and do UI in the form of a blocking modal. This is just not in keeping with the general mode of interaction, which is event-based (show the message, get an event when it's closed).
You can work around it by doing the alert
in a macrotask instead:
this.service.uploadFile((error: any) => {
if (error) {
setTimeout(() => {
console.log(error);
alert("An error occured");
}, 0);
return;
}
this.onUploadCompleted()
});
...but really the solution is to stop using alert
, prompt
, and confirm
entirely.
Here's a fun example of micro and macro tasks: A promise completion is a microtask, whereas timer callbacks are macrotasks. The initial run of the script is also a macrotask, as is a DOM event callback. All of the microtasks queued by a macrotask are run before the next macrotask is run; e.g., they jump the queue. So with this:
// First, we set a timer callback for 0ms
setTimeout(() => {
console.log("timer fired");
}, 0);
// Now we get a promise that's *already* resolved and hook a callback
Promise.resolve().then(() => {
console.log("promise resolved");
});
// Now show a message demonstrating we got here before the promise resolution callback
console.log("got to the end");
...we see
got to the end promise resolved timer fired
...rather than
got to the end timer fired promise resolved
....which we would have gotten if all tasks were created equal.