2015-06-16 34 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的超时时间。 –