Chrome:调用'alert()'在微任务执行期间已弃用,并将被删除

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

本文关键字:删除 alert 调用 任务 Chrome 执行期      更新时间:2023-09-26

在我的web应用程序上工作时,特别是文件上传,Chrome在我调用警报后显示警告:

在微任务执行期间调用'alert()'已弃用,并将在2016年9月左右在M53中删除。详见https://www.chromestatus.com/features/5647113010544640

然而,我认为在我的情况下调用是合理的,我有点担心我的代码将无法工作,一旦M53发布。请注意,我没有将警报发布到生产环境,但对于测试来说,它是非常有价值的。

这句话的语境是:

我正在开发我的应用程序在typescript使用react。我用axios做http请求。http-post基本上是这样的:

axios.post("/upload/", data)
    .then((response: any) => {
        callback(undefined);
    })
    .catch((error: any) => {
        callback(error);
    });

然后在调用方法中,如果有错误,我会弹出警报,这样我就可以确保测试人员/开发人员会收到通知。像这样:

this.service.uploadFile((error: any) => {
    if (error) {
        console.log(error);
        alert("An error occured");
        return;
    }
    this.onUploadCompleted()
});

这是chrome显示警告的时候。

首先,我想知道警告是否合理,因为直到请求完成并返回错误之后才显示警告。所以我很确定它没有阻塞任何东西。

如果它是合理的,我可以做些什么来显示警报?

是的,警告是合理的:您正在微任务中调用alert,在本例中是承诺完成。(参见事件循环上下文中微任务和宏任务的区别)

alert, promptconfirm是很久以前的遗物,它们有一个问题:它们完全中断了JavaScript的正常工作,并且可以通过完全暂停执行来违反其运行到完成的语义,就在作业队列中的作业(或事件循环中的任务)中间;JavaScript和HTML5规范在术语上有所不同),并以阻塞模式的形式做UI。这与基于事件的一般交互模式不一致(显示消息,在关闭时获取事件)。

您可以通过在任务中执行alert来解决它:

this.service.uploadFile((error: any) => {
    if (error) {
        setTimeout(() => {
            console.log(error);
            alert("An error occured");
        }, 0);
        return;
    }
    this.onUploadCompleted()
});

…但真正的解决方案是完全停止使用alert, promptconfirm


这里有一个有趣的宏任务和微任务的例子:承诺完成是一个微任务,而计时器回调是宏任务。脚本的初始运行也是一个宏任务,就像DOM事件回调一样。宏任务队列中的所有微任务都在下一个宏任务运行之前运行;例:他们插队。所以用这个:

// 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");

…我们看到

<>之前走到最后承诺解决定时器触发之前

…而不是

<>之前走到最后定时器触发承诺解决之前

…如果所有的任务都是相等的,我们就会得到。