2015-05-31 84 views
-1

我們正在研究排序算法的可視化,需要添加睡眠和等待邏輯以幫助可視化所選元素以及與其進行比較的元素。找到li'l bit後,我們發現了一個代碼「function sleep(milliseconds){...}」,它應該按照需要工作,但目前失敗了。如何在javascript中添加睡眠和等待邏輯

在函數insertionSort(){...}中,當前元素用紅色表示,與之比較的元素用藍色表示,一旦當前元素與另一個元素交換顏色該元件被再次改變爲從藍色白色(正常工作,經覈實使用調試器),但是在執行過程中,這些顏色轉換爲不可見(只顯示紅色元件每次迭代之後)

var element = function(value, color) 
 
{ 
 
    this.value = value; 
 
    this.color = color; 
 
}; 
 

 
var x = []; 
 
x[0] = new element(2, "white"); 
 
x[1] = new element(1, "white"); 
 
x[2] = new element(5, "white"); 
 
x[3] = new element(4, "white"); 
 
x[4] = new element(3, "white"); 
 
x[5] = new element(7, "white"); 
 
x[6] = new element(6, "white"); 
 
x[7] = new element(8, "white"); 
 
x[8] = new element(10, "white"); 
 
x[9] = new element(9, "white"); 
 

 

 
var i = 1; 
 
var context; 
 
var delayTime = 1000; 
 

 
function myFunction() 
 
{ 
 
    \t var bar = document.getElementById("bar"); 
 
    \t width = bar.width; 
 
    \t height = bar.height; 
 
    \t context = bar.getContext("2d"); 
 
    \t window.setInterval(insertionSort, 3000); 
 
} 
 

 
function insertionSort() 
 
{ 
 
    if(i>=0 && i<x.length) 
 
    { 
 
     \t 
 
\t \t var j = i; 
 
\t \t x[j].color = "red"; 
 
\t \t drawGraph(j); 
 
\t \t while(j>0 && x[j-1].value > x[j].value) 
 
\t \t { 
 
\t \t 
 
\t \t \t x[j-1].color = "blue"; 
 
\t \t \t x[j].color = "red"; 
 
\t \t \t drawGraph(); 
 
\t \t \t //need to add delay here 
 
\t \t \t sleep(delayTime); 
 
\t \t \t //swap 
 
\t \t \t var temp = x[j]; 
 
\t \t \t x[j] = x[j-1]; 
 
\t \t \t x[j-1] = temp; 
 
\t \t \t drawGraph(); 
 
\t \t \t // and here... 
 
\t \t \t sleep(delayTime); 
 
\t \t \t 
 
\t \t \t x[j].color = "white"; 
 
\t \t \t drawGraph(); 
 
\t \t \t 
 
\t \t \t j = j-1; 
 
\t \t } 
 
\t \t x[j].color = "white"; 
 
\t \t i++; 
 
    \t } 
 
    \t else if(i>=x.length) 
 
    \t { 
 
    \t \t for(k=0;k<x.length;k++) 
 
    \t \t { 
 
\t \t  x[k].color = "white"; 
 
\t  } 
 
     \t drawGraph(); 
 
     \t i=-1; 
 
    \t } 
 
} 
 

 
function sleep(milliseconds) 
 
{ 
 
    \t var start = new Date().getTime(); 
 
    \t for (var i = 0; i < 1e7; i++) 
 
    \t { 
 
    \t if ((new Date().getTime() - start) > milliseconds) 
 
    \t { 
 
     \t \t break; 
 
    \t } 
 
    \t } 
 
} 
 

 
function drawGraph() 
 
{ \t 
 
\t context.StrokeStyle = "black"; 
 
\t context.clearRect (0 , 0 , width, height); 
 
    for(k=0;k<x.length;k++) 
 
    {  
 
\t \t context.fillStyle = x[k].color; 
 
\t \t //x and y coordinate of top left corner of rectangle 
 
\t  context.strokeRect(400+k*20, 18, 20, x[k].value*10); 
 
\t  context.fillRect(400+k*20, 18, 20, x[k].value*10); 
 
\t  
 
    } 
 
}
<html> 
 
<head> 
 
    <script language="javascript" type="text/javascript" src="../p5.js"></script> 
 
    <!-- uncomment lines below to include extra p5 libraries --> 
 
\t <!--<script language="javascript" src="../addons/p5.dom.js"></script>--> 
 
    <!--<script language="javascript" src="../addons/p5.sound.js"></script>--> 
 
    <script language="javascript" type="text/javascript" src="sketch.js"></script> 
 
    <!-- this line removes any default padding and style. you might only need one of these values set. --> 
 
    <style> body {padding: 0; margin: 0;} </style> 
 
</head> 
 

 
<body> 
 
    
 
    <button onclick="myFunction()">Try it</button> 
 
    <canvas id="bar" width="1000" height="400" style="border:2px"></canvas> 
 
    
 
</body> 
 
</html>

+1

請[編輯]你的問題來解釋*完全*這個功能是如何失敗。感謝您提高問題的參考價值並使其更具責任感! –

+0

done ..感謝您指出 –

回答

2

該實現中使用的方法sleep()在任何編程語言中都會很糟糕,因爲它在等待時消耗大量CPU。然而,在JavaScript中,它尤其糟糕,因爲JavaScript程序需要經常放棄控制;不允許延長計算時間。例如,在Chrome瀏覽器中,Chrome會認爲該程序無響應,並會向用戶建議他們終止該程序。

但即使不是這樣,它不會產生所需的效果,我假設某些動畫發生在屏幕上,從一步到另一步都會有一些延遲。 JavaScript在瀏覽器中的工作方式是,當您的程序放棄控制權時,您對頁面所做的任何更改都會呈現;任何JavaScript代碼正在運行時屏幕上都沒有更新。如果您調用這樣的睡眠函數,那麼您並不是放棄控制,而是一直運行JavaScript,因此瀏覽器在此期間不會更新屏幕。它只會在你的整個插入方法返回時更新,並且瀏覽器有3000毫秒的時間窗口(來自你的setInterval)來照顧它自己的東西(渲染)。

不幸的是,您將不得不找到一種方法來分割該算法,以便您希望對用戶清楚可見的每個步驟都發生在其自己的定時回調中。

它可能會沿着線的東西:

function stepOne() { 
    do the first bit; 
    setTimeout(secondStep, delay) 
} 

secondStep() { 
    do some more stuff; 
    setTimeout(thirdStep, delay) 
} 

等。您控制動畫速度的方式是從一步到另一步的延遲參數。

這將是棘手的,尤其是因爲你不只是試圖動畫插入排序,但各種算法。那麼,你是否將它們全部分解爲:insertSortStepOne/Two/Three,shellSortStepOne/Two/Three?那會很難看。

取決於你是如何雄心勃勃,你多麼希望得到這個任務,你可能會探索ES6的這一特點(一個新的JavaScript版本)

function*

這是什麼讓你do是讓你的函數及其所有嵌套循環的結構幾乎保持原樣,但是你在它放棄控制的地方插入點。之後,它會從停止點繼續回叫。你會使用setTimeout或setInterval來做到這一點。我自己也沒有嘗試過,但它看起來非常酷。