2015-06-16 37 views
0

改變DOM元素,而其他進程正在運行

function subProcess() { 
 
    var f = []; 
 
    for (var i = 0; i < 10000; i++) { 
 
    for (var j = 0; j < 100000; j++) {} 
 
    f.push(1); 
 
    } 
 
} 
 

 
var statusElement = document.getElementById('status'); 
 

 
statusElement.innerHTML = "1"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>2"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>3"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>4"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>5"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>6"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>7"; 
 
subProcess(); 
 
statusElement.innerHTML += "<br/>8"; 
 
statusElement.innerHTML = "finished";
<div id='status'></div>

我有一個簡單的願望,我可以解決,但我的問題是正確的方式。

我有需要時間的過程。 該過程分爲幾個子過程。當每個子過程結束時,我想在某個段落元素上寫下它。

問題在於段落沒有更新,直到大進程結束,並且因爲瀏覽器被佔用,並且它將被釋放,它將更新DOM。

我知道我可以簡單地把每個子進程超時10毫秒或類似的東西,它正在做這項工作。

問題是唯一的方法? 這是一個函數,告訴瀏覽器做你的工作,並告訴你什麼時候完成?

例如,

// process start 

// writing the status to paragraph 
// wait till browser update the dom elements 
// sub process 1 start 

// writing the status to paragraph 
// wait till browser update the dom elements 
// sub process 2 start 

// writing the status to paragraph 
// wait till browser update the dom elements 
// sub process 3 start 

// writing the status to paragraph 
// wait till browser update the dom elements 
// process 1 ends 

我的問題是,處理時間對我很重要。我看到當我把0毫秒的超時它不工作的原因。因此每個子過程的10毫秒可以總結爲半秒。

+4

你能分享你試過的代碼嗎? –

+1

[Javascript is ** not ** a multithreaded language](http://stackoverflow.com/questions/16749664/single-thread-concept-of-javascript-running-in-browser) – Liam

+0

我意識到這一點。這不是我的注意。我的問題是如何等待瀏覽器使用更新UI,然後運行下一個過程。 –

回答

-1

我覺得你描述的正是旨在解決Web Workers

+0

你能詳細說一下嗎? [鏈接只有答案是勸阻](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) – Liam

+0

發送每個「長」的過程中另一個Web工作者。 –

+0

我對網絡工作者非常熟悉,並不總是解決方案。在我的例子中,我只是簡化了我的問題。在現實世界中,它非常複雜 - 服務器連接,異步回調以及更多... Web工作人員是乾淨的作用域,您需要將所有參數複製/傳輸給它,再加上包括腳本在內的這些工作需要太多工作 –

-1

有設置超時當一些最低限度。所以使用10ms是很好的。如果你堅持,這個帖子說它可能會降到4ms。 What is minimum millisecond value of setTimeout?

目前,我認爲除了setTimeout,clousure和callback的組合來解決您的問題外,沒有別的辦法。

var PIECE = 100; 
function print(string) { 
    var statusElement = document.getElementById('status'); 
    statusElement.innerHTML += ('' + string); 
} 
function subProcess(start, end) { 
    var i = 0, j = 0, finished = false; 
    var f = []; 
    // End comments meet. 
    if (start >= end) { 
    print('Finished'); 
    return; 
    } 

    var sub = function() { 
    var count = 0; 
    finished = true; 
    for (; i < 10000; ++i) { 
     for (; j < 10000; ++j) { 
     f.push(1); 
     ++count; 
     if (count >= PIECE) { 
      finished = false; 
      break; 
     } 
     } 
    } 
    if (finished) { 
     print(start); 
     subProcess(start + 1, end); 
     return; 
    } 
    setTimeout(sub, 10); 
    } 
    setTimeout(sub, 10); 
} 

JsFiddle

+0

這並不回答被問到的問題。 – Liam

+0

@Liam你認爲他在問什麼?在他的問題中,我認爲他知道設置的時間,在問題的最後,他也有關於爲什麼設置10ms的問題,我不確定他想問什麼,我不確定你是否回答了什麼他問。 – fuyushimoya

+0

對於所有解決多線程問題的人來說,這不是我的注意。我非常熟悉JavaScript,網絡工作者,單線程瀏覽器等等......而我的問題是,有沒有一種方法/功能可以等待瀏覽器完成其職責。爲前。 'window.updateUI()。then(function(){subProcess();})'like deferred –

0

我覺得你越來越感到困惑。

首先就像我說的JavaScript不是多線程的。它依次運行一個執行每個命令的線程,直到完成所有命令(It's actually a bit more complicated than that,但現在可以完成)。

其次subProcess()不是一個過程,它是一個函數調用。這將全部線性處理。認爲這是:

statusElement.innerHTML = "1"; 
var f = []; 
    for (var i = 0; i < 10000; i++) { 
    for (var j = 0; j < 100000; j++) {} 
    f.push(1); 
    } 
statusElement.innerHTML += "<br/>2"; 
var f = []; 
    for (var i = 0; i < 10000; i++) { 
    for (var j = 0; j < 100000; j++) {} 
    f.push(1); 
    } 
...etc 

第三一旦線程是自由的DOM時,纔會更新,你的線程是不是免費的,直到最後因爲subProcess()不斷做的事情。 A setTimeoutwould work because this would release the thread to do other things

+0

我知道你提到的3件事。我剛剛簡化了我的問題。具有簡單的功能。我的網站要複雜得多,並且包含真正的子過程,以及異步回調等。我的問題是在瀏覽器完成其職責時,知道了嗎?而不僅僅是設置一個10ms的超時時間。 –