Javascript:如何在执行 javascript 代码之间放置一个简单的延迟?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4912655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:44:44  来源:igfitidea点击:

Javascript: How to put a simple delay in between execution of javascript code?

javascriptjavascript-framework

提问by Vin

I have a for loop which iterates more than 10,000 times in a javascript code. The for loop creates and adds < div > tags into a box in the current page DOM.

我有一个 for 循环,它在 javascript 代码中迭代了 10,000 多次。for 循环在当前页面 DOM 中创建并添加 <div> 标签到一个框中。

for(i = 0; i < data.length; i++)
{
    tmpContainer += '<div> '+data[i]+' </div>';
    if(i % 50 == 0) { /* some delay function */ }
}
containerObj.innerHTML = tmpContainer;

i want to put a delay after every 50 < div > tags so what will be the code at the place of

我想在每 50 个 < div > 标签后放置一个延迟,那么在该位置的代码是什么

/* some delay function */

because its taking too much time to load all 10,000 < div > tags. i want to update the box in chunks of 50 < div > tags.

因为加载所有 10,000 个 <div> 标签需要太多时间。我想以 50 个 < div > 标签的块更新框。

thanks in advance.

提前致谢。

回答by David Tang

There's a handy trick in these situations: use a setTimeout with 0 milliseconds. This will cause your JavaScript to yield to the browser (so it can perform its rendering, respond to user input and so on), but without forcing it to wait a certain amount of time:

在这些情况下有一个方便的技巧:使用 0 毫秒的 setTimeout。这将导致您的 JavaScript 屈服于浏览器(因此它可以执行其渲染、响应用户输入等),但不会强制它等待一段时间:

for (i=0;i<data.length;i++) {
    tmpContainer += '<div> '+data[i]+' </div>';
    if (i % 50 == 0 || i == data.length - 1) {
        (function (html) { // Create closure to preserve value of tmpContainer
            setTimeout(function () {
                // Add to document using html, rather than tmpContainer

            }, 0); // 0 milliseconds
        })(tmpContainer);

        tmpContainer = ""; // "flush" the buffer
    }
}

Note: T.J. Crowder correctly mentions below that the above code will create unnecessary functions in each iteration of the loop (one to set up the closure, and another as an argument to setTimeout). This is unlikely to be an issue, but if you wish, you can check out his alternativewhich only creates the closure function once.

注意:TJ Crowder 在下面正确地提到,上面的代码将在循环的每次迭代中创建不必要的函数(一个用于设置闭包,另一个作为 的参数setTimeout)。这不太可能成为问题,但如果您愿意,可以查看他的替代方案,它只创建一次闭包函数。

A word of warning: even though the above code will provide a more pleasant rendering experience, having 10000 tags on a page is not advisable. Every other DOM manipulation will be slower after this because there are many more elements to traverse through, and a much more expensive reflow calculation for any changes to layout.

警告:尽管上面的代码会提供更愉快的渲染体验,但不建议在页面上使用 10000 个标签。在此之后,所有其他 DOM 操作都会变慢,因为要遍历的元素更多,并且对布局的任何更改都要进行更昂贵的回流计算。

回答by Darin Dimitrov

You could use the window.setTimeoutfunction to delay the execution of some code:

您可以使用window.setTimeout函数来延迟某些代码的执行:

if(i % 50 == 0) {
    window.setTimeout(function() {
        // this will execute 1 second later
    }, 1000);
}

But your javascript will continue to execute. It won't stop.

但是您的 javascript 将继续执行。它不会停止。

回答by T.J. Crowder

I'd break out the code creating the divs into a function, and then schedule execution of that function periodically via setTimeout, like this:

我会将创建divs的代码分解为一个函数,然后通过 定期安排该函数的执行setTimeout,如下所示:

function createThousands(data) {
    var index;

    index = 0;
    doAChunk();

    function doAChunk() {
        var counter;

        for (counter = 50; counter > 0; --counter) {
            // Are we done?
            if (index >= data.length) {
                // Yup
                return;
            }

            // ...create a div...

            // Move to the next
            ++index;
        }

        // Schedule the next pass
        setTimeout(doAChunk, 0); // 0 = defer to the browser but come back ASAP
    }
}

This uses a single closure, doAChunkto do the work. That closure is eligible for garbage collection once its work is done. (More: Closures are not complicated)

这使用单个闭包doAChunk来完成工作。一旦工作完成,该闭包就有资格进行垃圾收集。(更多:闭包并不复杂

Live example

活生生的例子

回答by Gergely Fehérvári

it takes much time because the reflows. you should create a document fragment and then adding the brats.

因为回流需要很多时间。您应该创建一个文档片段,然后添加小子。

When does reflow happen in a DOM environment?

什么时候在 DOM 环境中发生回流?

Javascript Performance - Dom Reflow - Google Article

Javascript 性能 - Dom 回流 - Google 文章

sleeping will not solve your problem

睡觉不能解决你的问题

on the other hand, you creating a string containing the innerhtml and the add to innerhtml. the string stuff really dont needs a big performance, but when you execute the .innerhtmlcommand, it starts a process, which parse your string and creating elements and appending them. you cant interrupt or add a delay.

另一方面,您创建了一个包含innerhtml 和添加到innerhtml 的字符串。字符串的东西真的不需要很大的性能,但是当您执行.innerhtml命令时,它会启动一个过程,该过程解析您的字符串并创建元素并附加它们。您不能中断或添加延迟。

the innerhtml process cannot be sleeped or interrupted.

所述的innerHTML过程不能sleeped或中断。

you need to generate the elements one by one, and after 50 elemnts added, create a settimeout delay.

你需要一个一个生成元素,添加50个元素后,创建一个settimeout延迟。

var frag = document.createDocumentFragment();

function addelements() {

   var e;
   for(i=0;i<50;++i) {
       e = document.createElement('div');
       frag.appendChild(e);
   }
   dest.appendChild(frag);
   window.setTimeout(addelements,1000);

}

回答by Kaushik

Here is the real trick to put a delay in javascript without hanging the browser. You need to use a ajax function with synchronous method which will call a php page and in that php page you can use the sleep() php function ! http://www.hklabs.org/articles/put-delay-in-javascript

这是在不挂起浏览器的情况下延迟 javascript 的真正技巧。您需要使用带有同步方法的 ajax 函数,该函数将调用一个 php 页面,并且在该 php 页面中您可以使用 sleep() php 函数! http://www.hklabs.org/articles/put-delay-in-javascript