2011-02-06 32 views
8

Tôi có vòng lặp for lặp lại nhiều hơn 10.000 lần trong mã javascript. Vòng lặp for tạo và thêm các thẻ < div> vào một hộp trong DOM trang hiện tại.Javascript: Làm thế nào để đặt một sự chậm trễ đơn giản ở giữa thực thi mã javascript?

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

tôi muốn đặt một sự chậm trễ sau mỗi 50 < div> thẻ vì vậy những gì sẽ được mã tại nơi

/* some delay function */ 

vì dùng nó quá nhiều thời gian để tải tất cả 10.000 < div> thẻ. tôi muốn cập nhật hộp theo khối 50 < div> thẻ.

cảm ơn trước.

Trả lời

15

Có một mẹo hữu ích trong các trường hợp sau: sử dụng setTimeout với 0 mili giây. Điều này sẽ khiến bạn hoạt Javascript để mang lại cho trình duyệt (vì vậy nó có thể thực hiện vẽ của mình, đáp ứng với đầu vào người dùng và vân vân), nhưng mà không buộc nó phải chờ một thời gian nhất định:

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: TJ Crowder chính xác đề cập bên dưới rằng mã trên sẽ tạo ra các chức năng không cần thiết trong mỗi lần lặp của vòng lặp (một để thiết lập đóng cửa, và một khác làm đối số cho setTimeout). Đây không phải là một vấn đề, nhưng nếu bạn muốn, bạn có thể kiểm tra his alternative mà chỉ tạo ra các chức năng đóng cửa một lần.

Cảnh báo: mặc dù mã trên sẽ cung cấp trải nghiệm hiển thị thú vị hơn, nhưng không nên khuyến khích sử dụng 10000 thẻ trên trang. Mỗi thao tác DOM khác sẽ chậm hơn sau này bởi vì có nhiều yếu tố hơn để đi qua, và một tính toán reflow đắt hơn nhiều cho bất kỳ thay đổi bố trí.

+1

Điều đó sẽ hiệu quả, nhưng hai nhận xét: 1. Việc tạo ** hàm ** mới không cần thiết mỗi khi bạn đạt đến 50 div. Đó là 199 chức năng không cần thiết. Có lẽ không sao, nhưng vẫn còn, tránh được. 2. Sẽ hiệu quả hơn khi xây dựng HTML trong một chuỗi các chuỗi và sau đó sử dụng 'a.join (" ")' để tạo một chuỗi lớn khi bạn hoàn thành, hơn là sử dụng chuỗi nối để xây dựng HTML. –

+0

@ T.J. Bạn có quyền về cả hai điểm đó, nhưng tôi không bận tâm vì sự đơn giản: 1. Tạo chức năng hiếm khi là vấn đề về hiệu năng, đặc biệt là khi nút cổ chai của bạn là DOM, 2. nối chuỗi chỉ là một vấn đề trên IE, và thường nhanh hơn trong các trình duyệt khác, nhưng ngay cả đối với IE, vì tôi đang đặt lại 'tmpContainer' thành một chuỗi rỗng, các chuỗi không bao giờ trở nên lớn;) –

+0

giải pháp thực sự tốt đẹp. –

2

Bạn có thể sử dụng chức năng window.setTimeout để trì hoãn việc thực hiện một số mã:

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

Nhưng javascript của bạn sẽ tiếp tục thực hiện. Nó sẽ không dừng lại.

1

Tôi muốn thoát ra khỏi các mã tạo div s vào một chức năng, và sau đó sắp xếp thực hiện các chức năng nhiệm vụ thường xuyên qua setTimeout, như thế này:

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 
    } 
} 

này sử dụng một kết thúc duy nhất, doAChunk làm công việc. Việc đóng cửa đó đủ điều kiện để thu gom rác thải khi công việc của họ được thực hiện. (Xem thêm: Closures are not complicated)

Live example

+0

không giải quyết được sự cố của bạn –

+0

@fehergeri: *Vấn đề của tôi? Huh? –

+0

@fehergeri: Ồ, tôi hiểu, bạn có nghĩa là * vấn đề của mình *. Tôi đã giải quyết vấn đề không thực hiện cập nhật tạm thời; reflow là cái gì khác hoàn toàn. –

1

phải mất nhiều thời gian vì chỉnh lại dòng. bạn nên tạo một đoạn tài liệu và sau đó thêm các brats.

When does reflow happen in a DOM environment?

Javascript Performance - Dom Reflow - Google Article

ngủ sẽ không giải quyết được vấn đề của bạn

mặt khác, bạn tạo ra một chuỗi chứa innerHTML và tiện ích để innerHTML.các công cụ chuỗi thực sự không cần một hiệu suất lớn, nhưng khi bạn thực hiện lệnh .innerhtml, nó bắt đầu một quá trình, phân tích cú pháp chuỗi của bạn và tạo các phần tử và thêm chúng. bạn không thể làm gián đoạn hoặc thêm một sự chậm trễ.

quá trình innerhtml không thể bị ngủ hoặc bị gián đoạn.

bạn cần tạo từng phần tử và sau 50 lần thêm elemnt, hãy tạo thời gian chờ giải quyết.

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); 

} 
-1

Đây là mẹo thực sự để trì hoãn javascript mà không cần treo trình duyệt. Bạn cần sử dụng chức năng ajax với phương thức đồng bộ sẽ gọi trang php và trong trang php đó, bạn có thể sử dụng hàm sleep() php! http://www.hklabs.org/articles/put-delay-in-javascript

+2

Lưu ý rằng [câu trả lời chỉ có liên kết] (http://meta.stackoverflow.com/tags/link-only-answers/info) không được khuyến khích, các câu trả lời SO phải là điểm cuối của việc tìm kiếm giải pháp (so với nhưng một điểm dừng khác của tài liệu tham khảo, mà có xu hướng để có được cũ theo thời gian). Vui lòng xem xét thêm bản tóm tắt độc lập tại đây, giữ liên kết dưới dạng tham chiếu. – kleopatra

Các vấn đề liên quan