Chrome: Invoking 'alert()' during microtask execution is deprecated and will be removed

前端 未结 1 714
野趣味
野趣味 2021-01-21 09:24

While working on my web app, specifically file uploads, Chrome displayed a warning after I called an alert:

Invoking \'alert()\' during microtask executio

相关标签:
1条回答
  • 2021-01-21 09:57

    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.

    0 讨论(0)
提交回复
热议问题