2011-04-18 134 views
0
function draw(data) 
{ 
var i = 0; 
var checkduplicates = new Array(); 
drawOne(i); 
//console.log(checkduplicates) Problem!!!; 

function drawOne(i) 
{ 
     //photos is a object that has been omitted for simplicity 
    var picinfo = photos[Math.floor(Math.random()*photos.length)]; 
    checkduplicates.push(picinfo); 

    img.onload = function() 
    { 
     var ctx = document.getElementsByClassName("canvas")[i].getContext('2d'); 
     // Draw pieces 
     ctx.drawImage(img,0,0,132,150); 
     //ctx.fillText("haha",0,0); 
     ctx.drawImage(frame,0,0,133,152); 
     i++; 
     if (i != canvaslength) 
     { 
      drawOne(i); 
     } 
    } 
    //console.log(checkduplicates.length); 
} 
} 

嘿,我聲明的繪製函數內的drawOne功能,從而使局部變量checkduplicates與上述內部功能drawOne訪問。但是,在drawOne函數運行16次之後,數組checkduplicates應該填充有對象,這由drawOne中的console.log證明,顯示了16個對象在數組中。但是,我標記爲「Problem」的console.log函數顯示該數組只有第一個對象,而其他console.logs則顯示該數組已充滿對象。我不明白爲什麼,因爲修改數組的唯一方法是通過已被調用了16次的「push」方法,並且如果我註釋掉img.onload部分,console.log中的註釋「problem」顯示數組充滿了對象。爲了簡單起見,我故意省略了其他代碼,並且我的螢火蟲不會抱怨錯誤。謝謝陣列不能被填充

+0

等待 - 「我」從哪裏來?和「照片」?和「checkduplicates」?你還沒有發佈足夠的代碼。 – Pointy 2011-04-18 23:56:53

+0

我初始化爲0;我會修好它。謝謝 – 2011-04-18 23:58:14

回答

2

由於您使用的是異步遞歸,所以在第一次迭代之後,將返回到drawOne的初始調用。當第一個圖像加載完畢並且退出draw函數時,迭代將繼續,以便瀏覽器重新獲得控制權,以便它可以處理事件。

因此,在第一次迭代後數組只包含單個項目根本就不是問題,這是您使用的迭代方法的預期結果。

+0

好的,但我仍然不明白,如何內部console.log顯示該數組已填充,但外部console.log顯示該數組只保存一個對象。但它們不是同一個陣列嗎?應該只有一個與「checkduplicates」關聯的內存地址?謝謝 – 2011-04-19 00:42:37

+0

@Clinteney Hui:這是一樣的陣列,但在不同的時間點。首先執行一次「drawOne」日誌記錄,顯示一個長度,然後執行「Draw」日誌記錄,顯示相同的結果。之後,加載第一個圖像並處理第一個'onload'事件,並且'drawOne'中的日誌記錄顯示了兩個長度。然後按照剩餘的'onload'事件增加數組的大小。數組長度不可能是'Draw'函數內的數組之外的任何東西,因爲只要您在函數內部,就不會處理第一個'onload'事件。 – Guffa 2011-04-19 01:29:35

+0

非常感謝你解釋這一點。 – 2011-04-19 10:34:26