在我的网络应用上工作时,特别是文件上传,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);
});
然后在调用方法中,如果出现错误,我会弹出一个警告,这样我就可以确定测试人员/开发人员会收到通知。有点像这样:
this.service.uploadFile((error: any) => {
if (error) {
console.log(error);
alert("An error occured");
return;
}
this.onUploadCompleted()
});
这是chrome显示警告的时候。
首先,我想知道警告是否合理,因为警报会在请求完成并且返回错误之后显示。所以我很确定它不会阻挡任何东西。
如果合理,可以做什么,所以我可以显示警报?
答案 0 :(得分:12)
是的,警告是合理的:您在微任务中调用alert
,在这种情况下是承诺完成。 (见Difference between microtask and macrotask within an event loop context。)
alert
,prompt
和confirm
是一个很久以前的文物,它们有一个问题:它们完全打断了JavaScript的正常运行,可以说违反了它的运行方式-completion语义通过完全挂起执行,就在作业队列中的作业中间(或来自事件循环的任务; JavaScript和HTML5规范在术语上有所不同),并以阻塞模式的形式执行UI。这与基于事件的一般交互模式不一致(显示消息,在事件关闭时获取事件)。
您可以通过执行宏任务中的alert
来解决此问题:
this.service.uploadFile((error: any) => {
if (error) {
setTimeout(() => {
console.log(error);
alert("An error occured");
}, 0);
return;
}
this.onUploadCompleted()
});
...但实际上解决方案是完全停止使用alert
,prompt
和confirm
。
以下是微观和宏任务的有趣示例:承诺完成是微任务,而计时器回调是 macrotasks 。脚本的初始运行也是一个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");
......我们看到了
got to the end promise resolved timer fired
...而不是
got to the end timer fired promise resolved
....如果所有任务都是平等的,我们就会得到它。