javascript - Javascript 中的长任务

标签 javascript jquery html

为什么在 following code我一次看到整个页面?谢谢!

HTML:

<div></div>

CSS:

div {
    width: 100px;
    height: 300px;
    border: 1px solid black;
    text-align: center;
}

Javascript:

$(function() {
    for (var i=0; i<15; i++) {
        sleep(100);
        $("div").append("<span>--- " + i + " ---<br /></span>");
    }

    function sleep(milliseconds) {
        var start = new Date().getTime();
        for (var i = 0; i < 1e7; i++) {
            if ((new Date().getTime() - start) > milliseconds){
                break;
            }
        }
    }
});

最佳答案

因为网络浏览器上的 Javascript 是单线程的(尽管这种情况正在改变;见下文),并且当(主)Javascript 线程繁忙时,几乎没有浏览器更新其 UI。您的 sleep 函数所做的就是阻止所有内容 100 毫秒,它不会让浏览器执行任何其他操作,例如更新其 UI(例如,不会“yield”)。

有几种方法可以完成您想要做的事情:

  1. 使用新的 web workers东西;但请注意,它是 not widely-supported yet .

  2. 使您的循环成为一个通过 setTimeout 调用自身的函数。这样,您的代码就会屈服于浏览器并让它更新其 UI。

下面是一个简单示例,说明如何将上面的 #2 应用到您的代码中:

$(function() {
    var i;

    doOne();

    function doOne() {
        $("div").append("<span>--- " + i + " ---<br /></span>");
        if (i++ < 15) {
            setTimeout(doOne, 0);   // <== Won't really be zero, browsers clamp it at ~10
        }
    }

});

如果你有很多循环迭代(例如,几百次而不是 15 次),那么在每次迭代中执行其中的一部分而不是在每次迭代中屈服可能是值得的;产量需要可测量的时间(通常约为 10-15 毫秒)。

关于javascript - Javascript 中的长任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2888221/

相关文章:

javascript - 等待某物停止来触发功能

javascript - backbone.js 在事件(发泄)完成时做些什么?

javascript - 如何减少 jquery 代码中的行数

html - 如何从 Angular 中的 JSON 列表中获取值?

javascript - 函数不会更新变量

javascript - 定时 promise 解决在之前用时间解决一次后立即返回

javascript - 在谷歌地图上更改手机的缩放比例

javascript - 在 onmouseover 事件上调用对象的类方法 HTML Javascript

javascript - 如何避免基础垂直标签网址?

jquery - 加载后如何在绝对定位的元素周围附加边距或填充?