我正在使用jQuery将动态生成的内容块列表添加到页面中。在我的情况下生成一个内容块需要一些时间,因此我希望浏览器在添加时立即显示生成的块,而浏览器不会同时显示所有生成的块。以下是我的Javascript代码在概念中的流程:
var results = $('#results');
var i;
for (i = 0; i < 20; i++) {
var block = Handlebars-generated-content;
results.append(block);
var more = = Handlebars-generated-content;
block.append(more);
}
当我的页面加载时,浏览器最初是空白的,访问者必须等待,然后一次显示所有添加的块。我希望浏览器在添加时可以显示一个块,这样访问者可以立即看到部分内容而无需等待更长时间。
答案 0 :(得分:4)
原因是你正在使用for循环,它是同步的;它将在一个“框架”中运行整个循环以及所有后续内容生成。
相反,您应该使用“异步循环”。这包括创建一个函数,并在每一代之后使用零毫秒setTimeout()
递归调用它。超时使浏览器有机会进行渲染,以便您的元素更快地显示出来。
var items = ['first', 'second', 'third', 'fourth', 'fifth'];
var index = 0;
function asyncLoop() {
// get our current item based on the index
var item = items[index];
// do your work here
$('#results').append('<ul>' + item + '</ul>');
// increase the index by 1
index++;
// keep looping if the index isn't at the end yet
if (index < items.length) {
// call ourselves using a timeout to give the browser a change to render
// intentionally set to 500ms to make this more obvious, set it to 0 normally
setTimeout(asyncLoop, 500);
}
}
// start the loop
asyncLoop();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="results">
</ul>
这种方法的唯一缺点是每次超时执行一次生成可能会在操作之间引入额外的延迟,因为在大多数浏览器上超时通常默认为最小约4ms。为了解决这个问题,您可能希望每个“循环”执行一小组操作以优化过程。
值得注意的是,这不是线程,只是异步循环。处理将始终按顺序执行,异步方面只是意味着它不会一次处理所有内容。