Chrome:在微任务执行期间调用“alert()”已被弃用,并将被删除 [英] Chrome: Invoking 'alert()' during microtask execution is deprecated and will be removed

查看:181
本文介绍了Chrome:在微任务执行期间调用“alert()”已被弃用,并将被删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在调用我的网络应用程序,特别是文件上传时,Chrome在我呼叫警报后显示一条警告:


调用'alert )'在执行微任务时已被弃用,并将于2016年9月左右在M53中删除。请参阅 https:// www。 chromestatus.com/features/5647113010544640 了解更多详情。


然而,我认为在我的情况下,我有点担心,一旦M53发布,我的代码将无法工作。请注意,我并没有将这些提示发送到生产环境,但是对于测试来说,这非常有价值。



情况:

我正在使用反应在打字稿中开发我的应用程序。我使用 axios 来执行http请求。基本上,http-post看起来像这样:

  axios.post(/ upload /,data)
。然后((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显示警告时。



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



如果有理由,可以做些什么以便我可以显示警报?$ b $是的,警告是有道理的:你在一个微任务中调用 alert ,在这种情况下承诺完成。 (请参阅 微分任务与宏任务之间的区别)



alert 提示和确认是过去一段时间的遗迹,并且存在一个问题:它们完全中断JavaScript的正常工作并且可能违反其运行完成暂停执行,正好在作业队列中的作业中(或来自事件循环的任务; JavaScript和HTML5规范在术语上有所不同),并以阻止模式的形式进行UI。这不符合基于事件的通用交互模式(显示消息,关闭时获取事件)。



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

  this.service.uploadFile((error:any)=> {
if(error){
setTimeout(()=> {
console.log(error );
alert(发生错误);
},0);
return;
}

this.onUploadCompleted()
});

...但实际上解决方案是停止使用 alert 提示符确认完整。

< hr>

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



//首先,我们为0mssetTimeout设置一个计时器回调()=> {console.log(timer fired);},0); //现在我们得到一个已经*已经*解析并且挂接了callbackPromise.resolve()。然后(()=> {console.log(promise resolved);}); //现在显示一条消息,演示我们在promise解析之前得到的消息callbackconsole.log(到最后);

...我们看到

 


到最后
承诺解决
定时器被解雇

...而不是

 
到头了
定时器已解除
解约

....如果所有任务的创建都是平等的,那么我们就可以得到这些。


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

Invoking 'alert()' during microtask execution is deprecated and will be removed in M53, around September 2016. See https://www.chromestatus.com/features/5647113010544640 for more details.

However I think that in my situation the call is justified and am a little worried my code won't work once M53 is released. Note that I'm not shipping to production with the alerts, but for testing it is quite valuable.

The situation:

I am developing my app in typescript using react. I'm using axios to do http requests. Basically the http-post looks like this:

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

Then in the calling method I'm popping an alert if there's an error so I can be sure the tester/developer will be notified. Kinda like this:

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

    this.onUploadCompleted()
});

This is when chrome displays the warning.

First of all I'm wondering if the warning is justified, because the alert is shown until after the request is done and an error was returned. So I'm pretty sure it's not blocking anything.

If it is justified, what can be done so I can display the alert anyway?

解决方案

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. 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.

这篇关于Chrome:在微任务执行期间调用“alert()”已被弃用,并将被删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆