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

Sap*_*huA 3 javascript ajax google-chrome axios

在我的网络应用上工作时,特别是文件上传,Chrome在我发出提醒后显示警告:

在微任务执行期间调用'alert()'已弃用,将于2016年9月左右在M53中删除.有关详细信息,请参阅https://www.chromestatus.com/features/5647113010544640.

但是我认为在我的情况下,这个电话是合理的,并且有点担心一旦M53发布我的代码将无法工作.请注意,我没有使用警报运送到生产中,但是对于测试它非常有价值.

情况:

我正在使用react开发我的应用程序.我正在使用axios来做http请求.基本上http-post看起来像这样:

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

然后在调用方法中,如果出现错误,我会弹出一个警告,这样我就可以确定测试人员/开发人员会收到通知.有点像:

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

    this.onUploadCompleted()
});
Run Code Online (Sandbox Code Playgroud)

这是当chrome显示警告时.

首先,我想知道警告是否合理,因为警报会在请求完成并且返回错误之后显示.所以我很确定它不会阻挡任何东西.

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

T.J*_*der 12

是的,警告是合理的:你在微任务中调用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()
});
Run Code Online (Sandbox Code Playgroud)

......但真正的解决办法是停止使用alert,promptconfirm完全.


这里的微观和宏观的任务一个有趣的例子:一个承诺完成是microtask,而计时器回调是宏任务.脚本的初始运行也是一个macrotask,DOM事件回调也是如此.所有由macrotask排队的微任务都在下一个macrotask运行之前运行; 例如,他们跳了队列.所以这个:

// 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");
Run Code Online (Sandbox Code Playgroud)

...我们看

got to the end
promise resolved
timer fired

...而不是

got to the end
timer fired
promise resolved

....如果所有任务都是平等的,我们本可以得到的.