为什么UI不会在javascript

时间:2018-01-03 22:02:48

标签: javascript asynchronous

我有一个浏览器应用程序,我想在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);
    });
}

1 个答案:

答案 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;什么都不做。