2011-04-18 237 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