我有一个浏览器应用程序,我想在UI中更改一些文本以表示页面正在加载,然后运行一个很长的过程,并且一旦完成该过程就说明页面已完成加载。
使用下面编写的代码,当我调用ProperlyUpdatesUIAsync
时,我可以使用此代码,在长进程运行时更改文本,然后在长进程完成后再次更改以指示它完成了。
但是,当我使用DoesNotUpdateUIUntilEndAsync
方法时,UI在长进程完成之后才会更新,从不显示“加载”消息。
我是否误解了async
/ await
如何使用JavaScript?为什么它在一个案例中有效但在另一个案例中却没有?
async function ProperlyUpdatesUIAsync(numberOfImagesToLoad) {
$("#PageStatusLabel").text("Loading..");
await pauseExecutionAsync(2000);
$("#PageStatusLabel").text("Loaded");
}
// this method doesn't do anything other than wait for the specified
// time before allowing execution to continue
async function pauseExecutionAsync(timeToWaitMilliseconds) {
return new Promise(resolve => {
window.setTimeout(() => {
resolve(null);
}, timeToWaitMilliseconds);
});
}
async function DoesNotUpdateUIUntilEndAsync(numberOfImagesToLoad) {
$("#PageStatusLabel").text("Loading..");
await runLongProcessAsync();
$("#PageStatusLabel").text("Loaded");
}
async function runLongProcessAsync() {
// there is a for loop in here that takes a really long time
}
修改 我试验了一些东西,这个新的重构给了我想要的结果,但我不喜欢它。我将一个长时间运行的循环包装在一个setTimeout中,超时设置为10.如果值为10,则在运行循环之前更新UI。但是,值0或甚至1不允许UI更新,并且它继续表现为好像根本没有声明超时。 10似乎很随意。我真的可以依赖于每种情况下的工作吗?在更新UI之前,不应该异步/等待延迟执行,而不必在超时中包装所有内容吗?
async function runLongProcessThatDoesNotBlockUIAsync() {
return new Promise(resolve => {
window.setTimeout(() => {
// there is a for loop in here that takes a really long time
resolve(null);
}, 10);
});
}
答案 0 :(得分:1)
EDITED
runLongProcessAsync()中的代码永远不会让线程放弃更新。
尝试: -
<!DOCTYPE html>
<html>
<script type="text/javascript">
var keep;
async function DoesNotUpdateUIUntilEndAsync(numberOfImagesToLoad) {
document.getElementById("PageStatusLabel").innerHTML="Loading..";
p = new Promise((resolve) => {keep = resolve})
setTimeout(theRest,0); //let the Loading message appear
return p;
}
async function theRest(){
await runLongProcessAsync(); // Your await here is useless!
document.getElementById("PageStatusLabel").innerHTML="Loaded";
keep();
}
async function runLongProcessAsync() {
// there is a for loop in here that takes a really long time
for (var x=1; x<1000000000;x++){b=x^2}
}
</script>
<body onload="DoesNotUpdateUIUntilEndAsync(5)">
<p>Test</p>
<p id="PageStatusLabel"></p>
</body>
</html>
我不确定你在尝试什么,但我的猜测是你希望Web Worker给你另一个帖子。或者你不明白&#34;等待&#34;只是摆脱了回调的需要。如果您的代码纯粹是同步的,只需标记&#34; async&#34;什么都不做。