2011-04-29 30 views
2

我看到這裏有很多關於請求JavaScript睡眠函數的線程,我知道它只能使用setTimeoutsetInterval來完成。如何在需要休眠功能時重構JavaScript代碼?

我做一些使用greasemonkey的用戶腳本,並編寫了一個加載大量頁面並從中計算出一些內容的腳本。它可以工作,但我不想過快地請求頁面。

var html0=syncGet(url0); // custom function for sync ajax call. 
// fill the something array 
for(var i=0;i<something.length;i++) 
{ 
    // calculate url1,url2 using the array and the i variable 
    // do something with lots of local variables 
    var html1=syncGet(url1); 
    // I would put a sleep here. 
    // do something with the results 
    var html2=syncGet(url2); 
    // I would put a sleep here. 
    // do something with the results 
    // get url3 from the page loaded from url2 
    var html3=syncGet(url3); 
    // I would put a sleep here. 
    // do something with the results 
} 
// use the result of the for loop and lots of code will follow... 

實際的代碼有點複雜,比這個更長。

我爲不存在的睡眠函數哭泣(並理解爲什麼它是不可能的)如何重構這個使用setTimeout,setInterval函數並保持它的可讀性(和工作)呢?

回答

1

我也有類似的問題,即一個大循環是在一些舊的瀏覽器阻止整個瀏覽器,我解決它使用:

function handlenext(idx,length) { 
    idx++ 

    //do your stuff here base on idx. 


    if (idx < length) { 
     setTimeout(function(){handlenext(idx,length)},1) 
    } else { 
     initSuccessEnd() 
    } 
} 

var ln = something.length; 


if (ln>0) { 
    handlenext(0,ln); 
} else { 
    initSuccessEnd() 
} 

這裏initSuccessEnd是所有完成時調用回調函數..

+0

,您可以在setTimeout的改變「1」到別的東西.. – dwarfy 2011-04-29 08:51:16

2

例如這樣的:

var urls = ["your","u","r","l´s"]; 
var htmls = new Array(urls.length); 
var time = 1000; 
for(var i=0;i<urls.length;i++){ 
    (function(i){ 
     setTimeout(function(){ 
      htmls[i] = syncGet(urls[i]); 
      if(i == urls.length-1){ 
       //continue here 
      } 
     },time*i); 
    })(i); 
} 
0

經過研究,我認爲Mozilla的新的迭代器生成器的東西可能是最合適的。 (它是因爲FF2支持)

function doSomething() 
{ 
    //..... 
     var html=syncGet(url1); 
     yield true; 
     var html2=syncGet(url2); 
     yield true; 
     var html3=syncGet(url3); 
     yield true; 
    //...... 
    yield false; 
} 

function iteratorRunner(iterator,timeout) 
{ 
    if (iterator.next()) 
    { 
     setTimeout(function(){iteratorRunner(iterator,timeout)},timeout); 
    } 
    else 
    { 
     iterator.close(); 
    } 
} 

var iterator=doSomething(); // returns an iterator immediately 
iteratorRunner(iterator,1000); // runs the iterator and sleeps 1 second on every yield. 

我希望Greasemonkey會搞定......當然

+0

的Greasemonkey不能處理這個問題。 .. pfff – Calmarius 2011-05-05 09:16:13